--------------------------------------------------------
--  DDL for Package Body CA_BLACK_LIST_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_BLACK_LIST_TAPI" 
IS
  -- insert
PROCEDURE ins(
      p_FU_REC_ID IN CA_BLACK_LIST.FU_REC_ID%type DEFAULT NULL ,
      p_USER_ID   IN CA_BLACK_LIST.USER_ID%type DEFAULT NULL ,
      p_FU_ID     IN CA_BLACK_LIST.FU_ID%type DEFAULT NULL,
      OP_CODE  OUT number,
      OP_MSG OUT CA_ERR_CODE.ERR_MSG%TYPE )
IS
	user_not_exist_exception exception;
	user_not_reg_exception exception;
	user_lock_exception exception;
  e_have_hide exception;
	t_user_count number(1,0);
	t_reg_status number(1,0);
	t_lock_status number(1,0);
  t_hide_count number(1,0) default 0 ;
BEGIN
t_hide_count:=0;
	--检测权限
    select count(*) into t_user_count from common_user where login_id = p_USER_ID;
		  
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user  where login_id = p_USER_ID;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user where login_id = p_USER_ID;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
    
    select count(*) into t_hide_count from CA_BLACK_LIST   where user_id = p_USER_ID and fu_id =p_FU_ID and fu_rec_id = p_FU_REC_ID;
    if t_hide_count <> 0 then
      raise e_have_hide;
    end if;
    
    INSERT
    INTO CA_BLACK_LIST
      (
      --  REC_ID ,
        FU_REC_ID ,
        USER_ID ,
        DATELINE ,
        FU_ID
      )
      VALUES
      (
        --p_REC_ID ,
        p_FU_REC_ID ,
        p_USER_ID ,
        sysdate,
        p_FU_ID
      );
    OP_CODE:=1;
    OP_MSG:='添加黑名单成功';


	exception 
	
	when user_not_exist_exception then
		begin
		 SELECT ERR_CODE,ERR_MSG INTO OP_CODE,OP_MSG FROM CA_ERR_CODE WHERE ERR_CODE='-2';
		end;
	when user_not_reg_exception then
		begin
		  SELECT ERR_CODE,ERR_MSG INTO OP_CODE,OP_MSG FROM CA_ERR_CODE WHERE ERR_CODE='-5';
		end;
	when user_lock_exception then
		begin
			SELECT ERR_CODE,ERR_MSG INTO OP_CODE,OP_MSG FROM CA_ERR_CODE WHERE ERR_CODE='-3';
		end;
 when e_have_hide then
    begin
     SELECT ERR_CODE,ERR_MSG INTO OP_CODE,OP_MSG FROM CA_ERR_CODE WHERE ERR_CODE='-7';
    end;
	when others then
		begin
    	OP_MSG:=sqlerrm;
			OP_CODE:=sqlcode;
		
		end;
    
END;
-- update
PROCEDURE upd
  (
    p_REC_ID    IN CA_BLACK_LIST.REC_ID%type ,
    p_FU_REC_ID IN CA_BLACK_LIST.FU_REC_ID%type DEFAULT NULL ,
    p_USER_ID   IN CA_BLACK_LIST.USER_ID%type DEFAULT NULL ,
    p_DATELINE  IN CA_BLACK_LIST.DATELINE%type DEFAULT NULL ,
    p_FU_ID     IN CA_BLACK_LIST.FU_ID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_BLACK_LIST
  SET FU_REC_ID = p_FU_REC_ID ,
    USER_ID     = p_USER_ID ,
    DATELINE    = p_DATELINE ,
    FU_ID       = p_FU_ID
  WHERE REC_ID  = p_REC_ID;
END;
-- del
PROCEDURE del(
    p_REC_ID IN CA_BLACK_LIST.REC_ID%type )
IS
BEGIN
  DELETE FROM CA_BLACK_LIST WHERE REC_ID = p_REC_ID;
END;

--成功示例：(38,33,35)
--失败示例:)
FUNCTION GET_BLACK_LIST(
	IP_USER_ID IN 	COMMON_USER.LOGIN_ID%TYPE,
	IP_FU_ID IN MOBILE_APP.APP_MODEL_ID%TYPE
)
RETURN VARCHAR
IS
	BLACK_DATA VARCHAR2(100) DEFAULT '';
	SEL_CURSOR SYS_REFCURSOR;
	V_ROW CA_BLACK_LIST%ROWTYPE;
BEGIN
	OPEN 	SEL_CURSOR FOR 
		SELECT * FROM CA_BLACK_LIST 
		WHERE USER_ID =IP_USER_ID
			AND FU_ID =IP_FU_ID;
			
	LOOP 		
		FETCH SEL_CURSOR INTO V_ROW;
		
		EXIT WHEN SEL_CURSOR%NOTFOUND;
		
		BLACK_DATA:=BLACK_DATA||V_ROW.FU_REC_ID||',';
		
	END LOOP;
  CLOSE SEL_CURSOR;
	BLACK_DATA:=SUBSTR(BLACK_DATA,1,LENGTH(BLACK_DATA)-1)||'';
	DBMS_OUTPUT.PUT_LINE('BLACK_DATA{'||BLACK_DATA||'}');

	RETURN trim(BLACK_DATA);
	
	EXCEPTION
	WHEN NO_DATA_FOUND THEN
		BEGIN
    	DBMS_OUTPUT.PUT_LINE('NO DATA');
			RETURN null;
		END;
	
	
END;

END CA_BLACK_LIST_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_CART_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_CART_TAPI" 
IS
  -- insert
  
   procedure ins(ip_data in nvarchar2, op_ins_code out number )
  is
    --用户权限判断
    user_lock_exception exception;
    t_user_lock_status number(1,0);
  
    obj json;
    order_data_list json_list;
    obj_values json_value;
    t_iterator number(2,0);--迭代变量
    t_userid common_user.login_id%type;
    t_goods_id  ca_simple_food.record_id%type;
    t_goods_number number(2,0);
    t_goods_name ca_simple_food.food_name%type;
    t_cart_count number(1,0);
    
  begin
    obj :=json(ip_data);
    --清除之前已有的购物车数据
    
    --获取数组对象
  order_data_list := obj.get_values();
  
 -- order_data_list.print;
  obj_values:=order_data_list.get(1);
  order_data_list:=json_list(obj_values.to_char);
--  order_data_list.get(1).print;
   --数据迭代
  t_iterator :=1;
  for t_iterator in 1..order_data_list.count 
  loop
    --数据插入
  --  t_amount:=order_data_list.get(t_iterator).get('amount').get_number;
  obj_values:=order_data_list.GET(t_iterator);
  obj:=json(obj_values.to_char);
    
   
    t_userid:=obj.get('userid').get_string;
    t_goods_id:=obj.get('goods_id').get_number;
    t_goods_number:=obj.get('goods_number').get_number;
    t_goods_name:=obj.get('goods_name').get_string;
    
    --查询数据库
    select count(*)  into t_cart_count  from CA_CART where USER_ID = t_userid and GOODS_ID = t_goods_id;
    if t_cart_count > 0 then
    begin
      --update
        update CA_CART 
        set 
        GOODS_NAME = t_goods_name,
        GOODS_NUMBER = t_goods_number
        where USER_ID = t_userid and GOODS_ID = t_goods_id;
    end;
    else 
      if t_iterator= 1 then
      delete from CA_CART where USER_ID = t_userid;
      end if ;
      begin
        INSERT
        INTO CA_CART
          (
        --    REC_ID ,
            USER_ID ,
            GOODS_NUMBER ,
            GOODS_NAME ,
            GOODS_ID
          )
          VALUES
          (
         --   p_REC_ID ,
            t_userid ,
            t_goods_number ,
            t_goods_name ,
            t_goods_id
          );
      
      end;
    
    end if;
    
  end loop;
    
    COMMIT;
    op_ins_code:=1;
    
  exception 
  when no_data_found then
  ROLLBACK;
  op_ins_code :=0;
  when user_lock_exception then
   ROLLBACK;
  op_ins_code := -2;
  when others then
   ROLLBACK;
  op_ins_code:=-1;
    
  end;



 
  
 
-- update
PROCEDURE upd
  (
    p_REC_ID       IN CA_CART.REC_ID%type ,
    p_USER_ID      IN CA_CART.USER_ID%type ,
    p_GOODS_NUMBER IN CA_CART.GOODS_NUMBER%type DEFAULT NULL ,
    p_GOODS_NAME   IN CA_CART.GOODS_NAME%type DEFAULT NULL ,
    p_GOODS_ID     IN CA_CART.GOODS_ID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_CART
  SET USER_ID    = p_USER_ID ,
    GOODS_NUMBER = p_GOODS_NUMBER ,
    GOODS_NAME   = p_GOODS_NAME ,
    GOODS_ID     = p_GOODS_ID
  WHERE REC_ID   = p_REC_ID;
END;
-- del
PROCEDURE del(
    p_REC_ID IN CA_CART.REC_ID%type )
IS
BEGIN
  DELETE FROM CA_CART WHERE REC_ID = p_REC_ID;
END;


 PROCEDURE SEL_CART_BY_USERID(
    IP_USER_ID IN NVARCHAR2,
    OP_SEL_RESULT OUT SYS_REFCURSOR,
    OP_SEL_CODE OUT NUMBER
  )
IS
  user_lock_exception  exception;
  user_not_exist exception ;
  t_lock_status number(1,0);
  t_user_count number(1,0);
BEGIN
      --permisson check
    select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
  
    OPEN OP_SEL_RESULT FOR 
    SELECT * FROM CA_CART LEFT JOIN CA_SIMPLE_FOOD
    ON CA_CART.GOODS_ID  = CA_SIMPLE_FOOD.RECORD_ID
    WHERE USER_ID = IP_USER_ID;
    OP_SEL_CODE:=1;
  
exception
  when user_not_exist then
    OP_SEL_CODE:=-2;
  when   user_lock_exception then
  OP_SEL_CODE:=-3;
  WHEN NO_DATA_FOUND THEN
  OP_SEL_CODE:=0;
  when others then
   OP_SEL_CODE:=-1; 
END;

PROCEDURE CLEAR_CART(
    IP_USER_ID IN NVARCHAR2,
    OP_OPERATE_CODE OUT NUMBER
  )
  IS
   user_lock_exception  exception;
  user_not_exist exception ;
  t_lock_status number(1,0);
  t_user_count number(1,0);
  BEGIN
       --permisson check
    select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
    DELETE FROM CA_CART WHERE USER_ID =IP_USER_ID;
    COMMIT;
    OP_OPERATE_CODE:=1;
    
    exception
  when user_not_exist then
    OP_OPERATE_CODE:=-2;
    ROLLBACK;
  when   user_lock_exception then
  OP_OPERATE_CODE:=-3;
    ROLLBACK;
  when others then
   OP_OPERATE_CODE:=-1; 
    ROLLBACK;
  END;
END CA_CART_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_DB_ANAL
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_DB_ANAL" 
IS
  /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
  -- 增加

PROCEDURE ins(
    p_OBJECT_NAME IN CA_RUNTIME_ANAL.OBJECT_NAME%type DEFAULT NULL ,
    p_COUNT_TIME  IN CA_RUNTIME_ANAL.COUNT_TIME%type ,
    p_OBJECT_TYPE IN CA_RUNTIME_ANAL.OBJECT_TYPE%type ,
    p_AVER_TIME   IN CA_RUNTIME_ANAL.AVER_TIME%type DEFAULT NULL ,
    p_EXE_TIMES   IN CA_RUNTIME_ANAL.EXE_TIMES%type DEFAULT NULL )
AS
BEGIN

  INSERT
  INTO CA_RUNTIME_ANAL
    (
      OBJECT_NAME ,
      COUNT_TIME ,
      OBJECT_TYPE ,
      AVER_TIME ,
      EXE_TIMES
    )
    VALUES
    (
      p_OBJECT_NAME ,
      p_COUNT_TIME ,
      p_OBJECT_TYPE ,
      p_AVER_TIME ,
      p_EXE_TIMES
    );
    COMMIT;
    
END ;

  /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
  --更新
  PROCEDURE upd
    (
      p_OBJECT_NAME IN CA_RUNTIME_ANAL.OBJECT_NAME%type DEFAULT NULL ,
      p_RECORD_ID   IN CA_RUNTIME_ANAL.RECORD_ID%type ,
      p_COUNT_TIME  IN CA_RUNTIME_ANAL.COUNT_TIME%type ,
      p_OBJECT_TYPE IN CA_RUNTIME_ANAL.OBJECT_TYPE%type ,
      p_AVER_TIME   IN CA_RUNTIME_ANAL.AVER_TIME%type DEFAULT NULL ,
      p_EXE_TIMES   IN CA_RUNTIME_ANAL.EXE_TIMES%type DEFAULT NULL
    )
  IS
  BEGIN
    UPDATE CA_RUNTIME_ANAL
    SET OBJECT_NAME = p_OBJECT_NAME ,
      RECORD_ID     = p_RECORD_ID ,
      COUNT_TIME    = p_COUNT_TIME ,
      OBJECT_TYPE   = p_OBJECT_TYPE ,
      AVER_TIME     = p_AVER_TIME ,
      EXE_TIMES     = p_EXE_TIMES
    WHERE RECORD_ID=p_RECORD_ID;
  END;
  /*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
  --删除
  PROCEDURE del
     
  IS
  BEGIN
    DELETE FROM CA_RUNTIME_ANAL  ;
  END;
  /*=======================================================删除全部==============================================================*/
   PROCEDURE  DEL_BY_ID(
     IP_RECORD_ID IN CA_RUNTIME_ANAL.RECORD_ID%type 
  )
  IS
  BEGIN
    DELETE FROM CA_RUNTIME_ANAL WHERE RECORD_ID= IP_RECORD_ID;
    COMMIT;
  END;
END CA_DB_ANAL;

/
--------------------------------------------------------
--  DDL for Package Body CA_FOOD_CATEGORY_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_FOOD_CATEGORY_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_CATEGORY_NAME IN CA_FOOD_CATEGORY.CATEGORY_NAME%type DEFAULT NULL 
  --  p_CATEGORY_ID   IN CA_FOOD_CATEGORY.CATEGORY_ID%type 
    )
IS
BEGIN
  INSERT
  INTO CA_FOOD_CATEGORY
    (
      CATEGORY_NAME 
      --CATEGORY_ID
    )
    VALUES
    (
      p_CATEGORY_NAME 
    --  p_CATEGORY_ID
    );
END;
-- update
PROCEDURE upd
  (
    p_CATEGORY_NAME IN CA_FOOD_CATEGORY.CATEGORY_NAME%type DEFAULT NULL ,
    p_CATEGORY_ID   IN CA_FOOD_CATEGORY.CATEGORY_ID%type
  )
IS
BEGIN
  UPDATE CA_FOOD_CATEGORY
  SET CATEGORY_NAME = p_CATEGORY_NAME
  WHERE CATEGORY_ID = p_CATEGORY_ID;
END;
-- del
PROCEDURE del(
    p_CATEGORY_ID IN CA_FOOD_CATEGORY.CATEGORY_ID%type )
IS
BEGIN
  DELETE FROM CA_FOOD_CATEGORY WHERE CATEGORY_ID = p_CATEGORY_ID;
END;
    /*==============选择全部数据================================*/
  PROCEDURE SEL_ALL(
    OP_SEL_RESULT OUT SYS_REFCURSOR,
    OP_SEL_MESSAGE OUT NVARCHAR2
  )
  IS
  
  BEGIN
    OPEN OP_SEL_RESULT FOR
      SELECT * FROM CA_FOOD_CATEGORY ORDER BY  CATEGORY_ID ASC;
    OP_SEL_MESSAGE :='';
    
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      OP_SEL_MESSAGE:='NO DATA FOUND EXCEPTION';
    WHEN OTHERS THEN
      OP_SEL_MESSAGE := 'OTHERS EXCEPTION OCCURED CODE['||SQLCODE||'] ERRMSG['||SQLERRM||']';
  END  ;
  

END CA_FOOD_CATEGORY_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_FOOD_COMMENT_TAB
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_FOOD_COMMENT_TAB" 
IS
  -- insert
PROCEDURE ins(
    p_MARK_VALUE      IN CA_FOOD_COMMENT.MARK_VALUE%type DEFAULT NULL ,
    p_COMMENT_DATE    IN CA_FOOD_COMMENT.COMMENT_DATE%type DEFAULT NULL ,
    p_USER_ID         IN CA_FOOD_COMMENT.USER_ID%type DEFAULT NULL ,
    --p_RECORD_ID       IN CA_FOOD_COMMENT.RECORD_ID%type ,
    p_COMMENT_CONTENT IN CA_FOOD_COMMENT.COMMENT_CONTENT%type DEFAULT NULL ,
    p_COMMENT_TYPE    IN CA_FOOD_COMMENT.COMMENT_TYPE%type DEFAULT NULL ,
    p_REF_ID          IN CA_FOOD_COMMENT.REF_ID%type DEFAULT NULL ,
    p_PARENT_ID       IN CA_FOOD_COMMENT.PARENT_ID%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_FOOD_COMMENT
    (
      MARK_VALUE ,
      COMMENT_DATE ,
      USER_ID ,
     -- RECORD_ID ,
      COMMENT_CONTENT ,
      COMMENT_TYPE ,
      REF_ID ,
      PARENT_ID
    )
    VALUES
    (
      p_MARK_VALUE ,
      p_COMMENT_DATE ,
      p_USER_ID ,
    --  p_RECORD_ID ,
      p_COMMENT_CONTENT ,
      p_COMMENT_TYPE ,
      p_REF_ID ,
      p_PARENT_ID
    );
END;
-- update
PROCEDURE upd
  (
    p_MARK_VALUE      IN CA_FOOD_COMMENT.MARK_VALUE%type DEFAULT NULL ,
    p_COMMENT_DATE    IN CA_FOOD_COMMENT.COMMENT_DATE%type DEFAULT NULL ,
    p_USER_ID         IN CA_FOOD_COMMENT.USER_ID%type DEFAULT NULL ,
    p_RECORD_ID       IN CA_FOOD_COMMENT.RECORD_ID%type ,
    p_COMMENT_CONTENT IN CA_FOOD_COMMENT.COMMENT_CONTENT%type DEFAULT NULL ,
    p_COMMENT_TYPE    IN CA_FOOD_COMMENT.COMMENT_TYPE%type DEFAULT NULL ,
    p_REF_ID          IN CA_FOOD_COMMENT.REF_ID%type DEFAULT NULL ,
    p_PARENT_ID       IN CA_FOOD_COMMENT.PARENT_ID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_FOOD_COMMENT
  SET MARK_VALUE    = p_MARK_VALUE ,
    COMMENT_DATE    = p_COMMENT_DATE ,
    USER_ID         = p_USER_ID ,
    COMMENT_CONTENT = p_COMMENT_CONTENT ,
    COMMENT_TYPE    = p_COMMENT_TYPE ,
    REF_ID          = p_REF_ID ,
    PARENT_ID       = p_PARENT_ID
  WHERE RECORD_ID   = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_FOOD_COMMENT.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_FOOD_COMMENT WHERE RECORD_ID = p_RECORD_ID;
END;
END CA_FOOD_COMMENT_TAB;

/
--------------------------------------------------------
--  DDL for Package Body CA_FOOD_TYPE_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_FOOD_TYPE_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_TYPE_NAME IN CA_FOOD_TYPE.TYPE_NAME%type DEFAULT NULL 
   -- p_TYPE_ID   IN CA_FOOD_TYPE.TYPE_ID%type
   )
IS
BEGIN
  INSERT
  INTO CA_FOOD_TYPE
    (
      TYPE_NAME 
     -- TYPE_ID
    )
    VALUES
    (
      p_TYPE_NAME 
     -- p_TYPE_ID
    );
END;
-- update
PROCEDURE upd
  (
    p_TYPE_NAME IN CA_FOOD_TYPE.TYPE_NAME%type DEFAULT NULL ,
    p_TYPE_ID   IN CA_FOOD_TYPE.TYPE_ID%type
  )
IS
BEGIN
  UPDATE CA_FOOD_TYPE SET TYPE_NAME = p_TYPE_NAME WHERE TYPE_ID = p_TYPE_ID;
END;
-- del
PROCEDURE del(
    p_TYPE_ID IN CA_FOOD_TYPE.TYPE_ID%type )
IS
BEGIN
  DELETE FROM CA_FOOD_TYPE WHERE TYPE_ID = p_TYPE_ID;
END;



 /*==============选择全部数据================================*/
  PROCEDURE SEL_ALL(
    OP_SEL_RESULT OUT SYS_REFCURSOR,
    OP_SEL_MESSAGE OUT NVARCHAR2
  )
  IS
  
  BEGIN
    OPEN OP_SEL_RESULT FOR
      SELECT * FROM CA_FOOD_TYPE ORDER BY  TYPE_ID ASC;
    OP_SEL_MESSAGE :='';
    
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      OP_SEL_MESSAGE:='NO DATA FOUND EXCEPTION';
    WHEN OTHERS THEN
      OP_SEL_MESSAGE := 'OTHERS EXCEPTION OCCURED CODE['||SQLCODE||'] ERRMSG['||SQLERRM||']';
  END  ;
  
  
END CA_FOOD_TYPE_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_MERCHANT_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_MERCHANT_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_ODER_LIST        IN CA_MERCHANT.ODER_LIST%type DEFAULT NULL ,
    p_LAST_MODIFY      IN CA_MERCHANT.LAST_MODIFY%type DEFAULT NULL ,
    p_LOGIN_ID         IN CA_MERCHANT.LOGIN_ID%type DEFAULT NULL ,
    p_REG_IP           IN CA_MERCHANT.REG_IP%type DEFAULT NULL ,
    p_REG_DATE         IN CA_MERCHANT.REG_DATE%type DEFAULT NULL ,
    p_CONTACT_NAME     IN CA_MERCHANT.CONTACT_NAME%type DEFAULT NULL ,
    p_RECORD_ID        IN CA_MERCHANT.RECORD_ID%type ,
    p_CONTACT_PHONE    IN CA_MERCHANT.CONTACT_PHONE%type DEFAULT NULL ,
    p_MERCHANT_NAME    IN CA_MERCHANT.MERCHANT_NAME%type DEFAULT NULL ,
    p_NEW_ORDER        IN CA_MERCHANT.NEW_ORDER%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN CA_MERCHANT.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_MERCHANT_ADDRESS IN CA_MERCHANT.MERCHANT_ADDRESS%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_MERCHANT
    (
      ODER_LIST ,
      LAST_MODIFY ,
      LOGIN_ID ,
      REG_IP ,
      REG_DATE ,
      CONTACT_NAME ,
      RECORD_ID ,
      CONTACT_PHONE ,
      MERCHANT_NAME ,
      NEW_ORDER ,
      ENCRYPTPASSWORD ,
      MERCHANT_ADDRESS
    )
    VALUES
    (
      p_ODER_LIST ,
      p_LAST_MODIFY ,
      p_LOGIN_ID ,
      p_REG_IP ,
      p_REG_DATE ,
      p_CONTACT_NAME ,
      p_RECORD_ID ,
      p_CONTACT_PHONE ,
      p_MERCHANT_NAME ,
      p_NEW_ORDER ,
      p_ENCRYPTPASSWORD ,
      p_MERCHANT_ADDRESS
    );
END;
-- update
PROCEDURE upd
  (
    p_ODER_LIST        IN CA_MERCHANT.ODER_LIST%type DEFAULT NULL ,
    p_LAST_MODIFY      IN CA_MERCHANT.LAST_MODIFY%type DEFAULT NULL ,
    p_LOGIN_ID         IN CA_MERCHANT.LOGIN_ID%type DEFAULT NULL ,
    p_REG_IP           IN CA_MERCHANT.REG_IP%type DEFAULT NULL ,
    p_REG_DATE         IN CA_MERCHANT.REG_DATE%type DEFAULT NULL ,
    p_CONTACT_NAME     IN CA_MERCHANT.CONTACT_NAME%type DEFAULT NULL ,
    p_RECORD_ID        IN CA_MERCHANT.RECORD_ID%type ,
    p_CONTACT_PHONE    IN CA_MERCHANT.CONTACT_PHONE%type DEFAULT NULL ,
    p_MERCHANT_NAME    IN CA_MERCHANT.MERCHANT_NAME%type DEFAULT NULL ,
    p_NEW_ORDER        IN CA_MERCHANT.NEW_ORDER%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN CA_MERCHANT.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_MERCHANT_ADDRESS IN CA_MERCHANT.MERCHANT_ADDRESS%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_MERCHANT
  SET ODER_LIST      = p_ODER_LIST ,
    LAST_MODIFY      = p_LAST_MODIFY ,
    LOGIN_ID         = p_LOGIN_ID ,
    REG_IP           = p_REG_IP ,
    REG_DATE         = p_REG_DATE ,
    CONTACT_NAME     = p_CONTACT_NAME ,
    CONTACT_PHONE    = p_CONTACT_PHONE ,
    MERCHANT_NAME    = p_MERCHANT_NAME ,
    NEW_ORDER        = p_NEW_ORDER ,
    ENCRYPTPASSWORD  = p_ENCRYPTPASSWORD ,
    MERCHANT_ADDRESS = p_MERCHANT_ADDRESS
  WHERE RECORD_ID    = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_MERCHANT.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_MERCHANT WHERE RECORD_ID = p_RECORD_ID;
END;

PROCEDURE LOGIN(
  IP_USERNAME IN CA_MERCHANT.LOGIN_ID%TYPE,
  IP_PASSWORD IN CA_MERCHANT.ENCRYPTPASSWORD%TYPE,
  OP_OP_CODE OUT NUMBER,
  OP_SELECT_RESULT OUT SYS_REFCURSOR
)
IS
  user_not_exist_exception exception;
  user_lock_exception exception;
  invalid_password_exception exception;
  t_user_count number(1,0);
  t_user_lock_status number(1,0);
  t_user_password CA_MERCHANT.ENCRYPTPASSWORD%type;
BEGIN
  --检测用户是否存在
  select count(*) into t_user_count from CA_MERCHANT where login_id = IP_USERNAME;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  
  
  
  --检测用户是否被锁定
  select status into t_user_lock_status from  CA_MERCHANT where login_id = IP_USERNAME;
  if t_user_lock_status<>1 then
    raise user_lock_exception;
  end if;
  
  --检验密码是否正确 
  select ENCRYPTPASSWORD into t_user_password from  CA_MERCHANT where login_id = IP_USERNAME;
  
  if t_user_password <> IP_PASSWORD then
    raise invalid_password_exception;
  end if;
  
  --返回用户信息
  open OP_SELECT_RESULT for
    select * from CA_MERCHANT where login_id = IP_USERNAME;
  OP_OP_CODE := 1;

exception
when user_not_exist_exception then
  begin
      OP_OP_CODE:=-2;
       open OP_SELECT_RESULT for
       select '没有此用户' from dual;
  end;
when user_lock_exception then
  begin
      OP_OP_CODE:=-3;
       open OP_SELECT_RESULT for
        select '用户被锁定' from dual;
  end;
  when invalid_password_exception then
  begin
      OP_OP_CODE:=-4;
       open OP_SELECT_RESULT for
        select '错误密码' from dual;
  end;
  when others then
  begin
      OP_OP_CODE:=-1;
       open OP_SELECT_RESULT for
        select '其他错误' from dual;
  end;
END;
  PROCEDURE UPD_PASSWORD(
          IP_USERNAME IN CA_MERCHANT.LOGIN_ID%TYPE,
          IP_PASSWORD IN CA_MERCHANT.ENCRYPTPASSWORD%TYPE,
          OP_OP_CODE OUT NUMBER
   )
   IS
    user_not_exist_exception exception;
    user_lock_exception exception;
    invalid_password_exception exception;
    t_user_count number(1,0);
    t_user_lock_status number(1,0);
    t_user_password CA_MERCHANT.ENCRYPTPASSWORD%type;
   BEGIN
    --检测用户是否存在
  select count(*) into t_user_count from CA_MERCHANT where login_id = IP_USERNAME;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  
  
  
  --检测用户是否被锁定
  select status into t_user_lock_status from  CA_MERCHANT where login_id = IP_USERNAME;
  if t_user_lock_status<>1 then
    raise user_lock_exception;
  end if;
  
  --检验密码是否正确 
  select ENCRYPTPASSWORD into t_user_password from  CA_MERCHANT where login_id = IP_USERNAME;
  
  if t_user_password <> IP_PASSWORD then
    raise invalid_password_exception;
  end if;
  
  
  OP_OP_CODE := 1;

exception
when user_not_exist_exception then
  begin
      OP_OP_CODE:=-2;
  end;
when user_lock_exception then
  begin
      OP_OP_CODE:=-3;
  end;
  when invalid_password_exception then
  begin
      OP_OP_CODE:=-4;
  end;
  when others then
  begin
      OP_OP_CODE:=-1;
  end;
    
   END;
   
   
   
     PROCEDURE GET_LAST_MESSAGE(
       IP_USERNAME IN CA_MERCHANT.LOGIN_ID%TYPE,
       OP_NEW_PROM_COUNT OUT NUMBER       
   )IS
     user_not_exist_exception exception;
     user_lock_exception exception;
      t_user_count number(1,0);
      t_user_lock_status number(1,0);
   BEGIN
     --检测用户是否存在
  select count(*) into t_user_count from CA_MERCHANT where login_id = IP_USERNAME;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  
  
  
  --检测用户是否被锁定
  select status into t_user_lock_status from  CA_MERCHANT where login_id = IP_USERNAME;
  if t_user_lock_status<>1 then
    raise user_lock_exception;
  end if; 
   SELECT  NEW_ORDER INTO OP_NEW_PROM_COUNT from  CA_MERCHANT where login_id = IP_USERNAME;
   
   
   exception
when user_not_exist_exception then
  begin
      OP_NEW_PROM_COUNT:=-2;
  end;
when user_lock_exception then
  begin
      OP_NEW_PROM_COUNT:=-3;
  end;
  
  when others then
  begin
      OP_NEW_PROM_COUNT:=-1;
  end;
   END;
   
   
  
  
END CA_MERCHANT_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_MESSAGES_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_MESSAGES_TAPI" 
IS
  -- insert
  /*
  fu_id 定义如下:
  1:表示吃喝玩乐评论
  2：表示吃喝玩乐转发
  3:表示趣事评论
  4：表示趣事回复
  5:表示推送消息推送
  */
PROCEDURE ins(
  --  p_READER_LIST IN CA_MESSAGES.READER_LIST%type ,
   -- p_REC_ID      IN CA_MESSAGES.REC_ID%type ,
  ---  p_GEN_TIME    IN CA_MESSAGES.GEN_TIME%type ,
   -- p_READ_STATUS IN CA_MESSAGES.READ_STATUS%type ,
    p_TYPE_ID     IN CA_MESSAGES.TYPE_ID%type ,
    p_RECV_ID     IN CA_MESSAGES.RECV_ID%type ,
    p_TITLE       IN CA_MESSAGES.TITLE%type ,
    p_FU_ID       IN CA_MESSAGES.FU_ID%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_MESSAGES
    (
      READER_LIST,
      GEN_TIME,
      TYPE_ID ,
      RECV_ID ,
      TITLE ,
      FU_ID
    )
    VALUES
    (
      '',
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi'),
      p_TYPE_ID ,
      p_RECV_ID ,
      p_TITLE ,
      p_FU_ID
    );
    commit;
END;
-- update
PROCEDURE upd
  (
    p_READER_LIST IN CA_MESSAGES.READER_LIST%type ,
    p_REC_ID      IN CA_MESSAGES.REC_ID%type ,
    p_GEN_TIME    IN CA_MESSAGES.GEN_TIME%type ,
    p_READ_STATUS IN CA_MESSAGES.READ_STATUS%type ,
    p_TYPE_ID     IN CA_MESSAGES.TYPE_ID%type ,
    p_RECV_ID     IN CA_MESSAGES.RECV_ID%type ,
    p_TITLE       IN CA_MESSAGES.TITLE%type ,
    p_FU_ID       IN CA_MESSAGES.FU_ID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_MESSAGES
  SET READER_LIST = p_READER_LIST ,
    GEN_TIME      = p_GEN_TIME ,
    READ_STATUS   = p_READ_STATUS ,
    TYPE_ID       = p_TYPE_ID ,
    RECV_ID       = p_RECV_ID ,
    TITLE         = p_TITLE ,
    FU_ID         = p_FU_ID
  WHERE REC_ID    = p_REC_ID;
END;
-- del
PROCEDURE del(
    p_REC_ID IN CA_MESSAGES.REC_ID%type )
IS
BEGIN
  DELETE FROM CA_MESSAGES WHERE REC_ID = p_REC_ID;
END;


      PROCEDURE GET_LAST_MESSAGE(
       IP_USERNAME IN CA_MERCHANT.LOGIN_ID%TYPE,
       op_new_messages OUT NUMBER       
      )
      is
        user_not_exist_exception exception;
        user_not_reg_exception exception;
        user_lock_exception exception;
        t_user_count number(1,0);
        t_reg_status number(1,0);
        t_lock_status number(1,0);
        
        t_count1 number(2,0);
        t_count2 number(2,0);
      begin
		--检测用户权限
		select count(*) into t_user_count from common_user where login_id = IP_USERNAME;
      
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user where login_id = IP_USERNAME;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user  where login_id = IP_USERNAME;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
		
		select     count(*) into t_count1
              from CA_MESSAGES where RECV_ID = IP_USERNAME and READ_STATUS=0;
    
     select          count(*) into t_count2
                    
                    from CA_MESSAGES where RECV_ID = '*'  and ( DBMS_LOB.INSTR(READER_LIST,','||IP_USERNAME||',') = 0 or DBMS_LOB.INSTR(READER_LIST,','||IP_USERNAME||',') is null);
      op_new_messages:=t_count1+t_count2;
    exception 
		when user_not_exist_exception then
			begin
			op_new_messages:=-1;
			end;
		when user_not_reg_exception then
			begin
			op_new_messages:=-2;
			end;
		when user_lock_exception then
			begin
			op_new_messages:=-3;
			end;
		when others then
			begin
			op_new_messages:=-4;
			end;
			
	  end;
      
   PROCEDURE GET_MESSAGE(
    IP_PAGE_INDEX IN NUMBER,
    IP_PAGE_SIZE IN NUMBER,
	IP_USER_ID IN COMMON_USER.LOGIN_ID%TYPE,
	OP_SEL_RESULT OUT SYS_REFCURSOR,
	OP_OP_CODE OUT NUMBER
)
IS 
	user_not_exist_exception exception;
	user_not_reg_exception exception;
	user_lock_exception exception;
	t_user_count number(1,0);
	t_reg_status number(1,0);
	t_lock_status number(1,0);
	V_CUR_PAGE NUMBER;
  v_messages nvarchar2(200);
BEGIN
		select count(*) into t_user_count from common_user where login_id = IP_USER_ID;
		  
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user  where login_id = IP_USER_ID;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
	
	  V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	  
	   OPEN OP_SEL_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
	  
		 
	select         REC_ID ,
              GEN_TIME ,
              READ_STATUS ,
              TYPE_ID ,
              RECV_ID ,
              TITLE ,
              FU_ID 
              from CA_MESSAGES where RECV_ID = IP_USER_ID and READ_STATUS=0
  
  union
  
  select            REC_ID ,
									  GEN_TIME ,
									  READ_STATUS ,
									  TYPE_ID ,
									  RECV_ID ,
									  TITLE ,
									  FU_ID
                    
                    from CA_MESSAGES where RECV_ID = '*'  and ( DBMS_LOB.INSTR(READER_LIST,','||IP_USER_ID||',') = 0 or DBMS_LOB.INSTR(READER_LIST,','||IP_USER_ID||',') is null)
			 ORDER BY GEN_TIME DESC	
		 ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);	
  v_messages:='{count['||OP_SEL_RESULT%rowcount||']}';
		OP_OP_CODE:=1;
		
	exception 
	
		when user_not_exist_exception then
			begin
			OP_OP_CODE:=-1;
			 OPEN OP_SEL_RESULT FOR
			 select '用户不存在' from dual;
			end;
		when user_not_reg_exception then
			begin
			OP_OP_CODE:=-2;
			 OPEN OP_SEL_RESULT FOR
			 select '用户未注册' from dual;
			end;
		when user_lock_exception then
			begin
			OP_OP_CODE:=-3;
			 OPEN OP_SEL_RESULT FOR
			 select '用户被锁定' from dual;
			end;
    when no_data_found then
      begin
        	begin
			OP_OP_CODE:=-4;
			 OPEN OP_SEL_RESULT FOR
			 select '没有找到任何数据' from dual;
			end;
      end;
		when others then
			begin
			OP_OP_CODE:=-5;
			 OPEN OP_SEL_RESULT FOR
			 select '其他错误' from dual;
			end;
	
END;
    
    
    
    PROCEDURE MARK_READ(
      IP_REC_ID IN NUMBER,--记录ID
      TYPE_ID IN NUMBER,--栏目ID,传入该参数是因为有的消息是存放的标记队列
      IP_USER_ID IN COMMON_USER.LOGIN_ID%TYPE,
	  OP_OP_CODE OUT NUMBER--操作代码
    )
	IS
		user_not_exist_exception exception;
		user_not_reg_exception exception;
		user_lock_exception exception;
    user_mismatch_exception exception;
		t_user_count number(1,0);
		t_reg_status number(1,0);
		t_lock_status number(1,0);
		t_clob clob;
		m_clob clob;
    t_message nvarchar2(200);
		t_pos   number(20,0);
    t_user COMMON_USER.LOGIN_ID%TYPE;
	BEGIN
		--PERMISSION CHECK BEGIN
		select count(*) into t_user_count from common_user where login_id = IP_USER_ID;
		  
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user  where login_id = IP_USER_ID;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
	
	
		--消息参照表
		-- <item>1,吃喝玩乐评论</item>
        -- <item>2,吃喝玩乐转发</item>
        -- <item>3,理工趣事评论</item>
        -- <item>4,理工趣事回复</item>
        -- <item>5,学校公告通知</item>
        -- <item>6,校园活动通知</item>
        -- <item>7,信息反馈回馈</item>
        -- <item>8,兼职提醒</item>
	
		IF TYPE_ID = 1 OR TYPE_ID = 2 OR TYPE_ID = 3 OR TYPE_ID = 4 THEN
			BEGIN
				select RECV_ID into t_user from  CA_MESSAGES		WHERE REC_ID = IP_REC_ID;
        if     t_user <> IP_USER_ID then
          raise user_mismatch_exception;
        end if;
        
        
				UPDATE CA_MESSAGES 
				SET READ_STATUS = 1 
				WHERE REC_ID = IP_REC_ID;
				
				COMMIT;
				
				
			END;
		ELSIF TYPE_ID = 5 OR TYPE_ID = 6 OR TYPE_ID = 7 OR TYPE_ID = 8 THEN
		
			BEGIN
				
				--查询存储的数据
			select READER_LIST into m_clob from CA_MESSAGES WHERE REC_ID = IP_REC_ID for update;
			 --首先判定是否为空
			  if m_clob is null then--直接追加.执行后:,20101301012,
				select ','||IP_USER_ID||',' into m_clob from dual;
				--dbms_lob.append(m_clob,t_clob);--将用户加入到已读队列中 
				UPDATE CA_MESSAGES 
				SET READER_LIST = m_clob 
				WHERE REC_ID = IP_REC_ID;
        commit;
        --返回代码设置
				
			  else
				--判定用户是否已经阅读
				t_pos:=dbms_lob.instr(m_clob,','||IP_USER_ID||',');
				if t_pos=0 then
				  --不存在,执行：,20101301012,20101301012,
				   select  IP_USER_ID||',' into t_clob from dual;
				   dbms_lob.append(m_clob,t_clob);--将用户加入到已读队列中 
					--返回代码设置
					UPDATE CA_MESSAGES 
          SET READER_LIST = m_clob 
          WHERE REC_ID = IP_REC_ID;
          commit;
				end if;
				
			  end if;	
				
			END;
			
		END IF;
		
		OP_OP_CODE:=1;
	exception 
	
	when user_not_exist_exception then
		begin
		OP_OP_CODE:=-1;
	
		end;
	when user_not_reg_exception then
		begin
		OP_OP_CODE:=-2;
		
		end;
	when user_lock_exception then
		begin
		OP_OP_CODE:=-3;
		
		end;
	when no_data_found then
	  begin
		begin
		OP_OP_CODE:=-4;
	
		end;
	end;
	when others then
		begin
    t_message:='code:'||sqlcode||'msg:'||sqlerrm;
		OP_OP_CODE:=-5;
		
		end;
	END;
        
  
  
  
  
  
  
  PROCEDURE ALL_MESSAGES(
   IP_PAGE_INDEX IN NUMBER,--
   IP_PAGE_SIZE IN NUMBER,
   IP_USER_ID IN COMMON_USER.LOGIN_ID%TYPE,
   OP_SEL_RESULT OUT SYS_REFCURSOR,
   OP_OP_CODE OUT NUMBER
)IS

	user_not_exist_exception exception;
	user_not_reg_exception exception;
	user_lock_exception exception;
	t_user_count number(1,0);
	t_reg_status number(1,0);
	t_lock_status number(1,0);
	V_CUR_PAGE NUMBER;
	T_SELECT_RESULT  SYS_REFCURSOR;
	T_ROW CA_T_MESSAGES%ROWTYPE;
	T_CLOB CLOB;
	T_POS NUMBER(10,0);
  t_message nvarchar2(200);
BEGIN
	--PERMISSION CHECK BEGIN
	select count(*) into t_user_count from common_user where login_id = IP_USER_ID;
		  
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user  where login_id = IP_USER_ID;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
	
	 V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	
	--PERMISSION CHECK END
	DELETE FROM CA_T_MESSAGES;
  COMMIT;
	--选择所有数据到游标之中
	OPEN T_SELECT_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
	  
			SELECT    REC_ID ,
                TYPE_ID ,
							  GEN_TIME ,
                FU_ID,
                TITLE ,
                RECV_ID ,
							  READ_STATUS ,
							  READER_LIST
     FROM CA_MESSAGES
			WHERE RECV_ID = IP_USER_ID OR RECV_ID = '*'
			ORDER BY GEN_TIME DESC
			
			 
			 
		 ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);		
		
		
		--对游标进行处理
      
		 LOOP
			FETCH T_SELECT_RESULT INTO T_ROW;
			 Exit WHEN T_SELECT_RESULT%NOTFOUND;
			 
			 BEGIN
			 --对每一条数据进行处理
			--IF REV_ID <> '*'
				IF T_ROW.RECV_ID = IP_USER_ID THEN
					BEGIN
						--直接插入数据到临时表
						 INSERT
						  INTO CA_T_MESSAGES
							(
							  REC_ID ,
							  GEN_TIME ,
							  READ_STATUS ,
							  TYPE_ID ,
							  RECV_ID ,
							  TITLE ,
							  FU_ID
							)
							VALUES
							(
							  T_ROW.REC_ID ,
							  T_ROW.GEN_TIME ,
							  T_ROW.READ_STATUS ,
							  T_ROW.TYPE_ID ,
							  T_ROW.RECV_ID ,
							  T_ROW.TITLE ,
							  T_ROW.FU_ID
							); 
						
					END;
				ELSIF T_ROW.RECV_ID ='*' THEN
					BEGIN
						
						T_CLOB:=T_ROW.READER_LIST;
            
						T_POS:=DBMS_LOB.INSTR(T_CLOB,','||IP_USER_ID||',');
						--判定用户是否已经阅读
						
						IF T_POS = 0 OR T_POS IS NULL  THEN --UNREAD
							BEGIN
								INSERT
								  INTO CA_T_MESSAGES
									(
									  REC_ID ,
									  GEN_TIME ,
									  READ_STATUS ,
									  TYPE_ID ,
									  RECV_ID ,
									  TITLE ,
									  FU_ID
									)
									VALUES
									(
									  T_ROW.REC_ID ,
									  T_ROW.GEN_TIME ,
									  0,
									  T_ROW.TYPE_ID ,
									  T_ROW.RECV_ID ,
									  T_ROW.TITLE ,
									  T_ROW.FU_ID
									); 
							END;
						ELSE--READ
							BEGIN
								INSERT
								  INTO CA_T_MESSAGES
									(
									  REC_ID ,
									  GEN_TIME ,
									  READ_STATUS ,
									  TYPE_ID ,
									  RECV_ID ,
									  TITLE ,
									  FU_ID
									)
									VALUES
									(
									  T_ROW.REC_ID ,
									  T_ROW.GEN_TIME ,
									  1,
									  T_ROW.TYPE_ID ,
									  T_ROW.RECV_ID ,
									  T_ROW.TITLE ,
									  T_ROW.FU_ID
									); 
							END;
						END IF;
					
					
					END;
				END IF;
			END;
			 COMMIT;
		 END LOOP;
	
	
		--查询全部的数据
		 OPEN OP_SEL_RESULT FOR 	
			SELECT * FROM CA_T_MESSAGES ORDER BY GEN_TIME DESC;
		
		 OP_OP_CODE:=1;
		-- COMMIT;	--提交以至于清除临时表数据
		 
		 
	exception 
	
	when user_not_exist_exception then
		begin
		OP_OP_CODE:=-1;
		 OPEN OP_SEL_RESULT FOR
		 select '用户不存在' from dual;
		end;
	when user_not_reg_exception then
		begin
		OP_OP_CODE:=-2;
		 OPEN OP_SEL_RESULT FOR
		 select '用户未注册' from dual;
		end;
	when user_lock_exception then
		begin
		OP_OP_CODE:=-3;
		 OPEN OP_SEL_RESULT FOR
		 select '用户被锁定' from dual;
		end;
	when no_data_found then
	  begin
		begin
		OP_OP_CODE:=-4;
		 OPEN OP_SEL_RESULT FOR
		 select '没有找到任何数据' from dual;
		end;
	end;
	when others then
		begin
		OP_OP_CODE:=-5;
    t_message:='msg:'||sqlerrm;
		 OPEN OP_SEL_RESULT FOR
		 select '其他错误' from dual;
		end;

END;	
  
  
  
  
  
  
  
  
  
  
  
  
END CA_MESSAGES_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_NETWORK_PROCESS_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_NETWORK_PROCESS_TAPI" 
IS
  -- insert
 PROCEDURE ins(
      p_USER_ID           IN CA_NETWORK_PROCESS.USER_ID%type DEFAULT NULL ,
      p_CONTACT_TEL       IN CA_NETWORK_PROCESS.CONTACT_TEL%type DEFAULT NULL ,
      p_CONTACT_MOBILE    IN CA_NETWORK_PROCESS.CONTACT_MOBILE%type DEFAULT NULL ,
      p_BREAKDOWN_DESC    IN CA_NETWORK_PROCESS.BREAKDOWN_DESC%type ,
      p_BREAKDOWN_ADDRESS IN CA_NETWORK_PROCESS.BREAKDOWN_ADDRESS%type ,
      p_CONTACT_MAN       IN CA_NETWORK_PROCESS.CONTACT_MAN%type DEFAULT NULL,
      p_BREAKDOWN_TYPE    IN CA_NETWORK_PROCESS.BREAKDOWN_TYPE%type DEFAULT NULL,
      OP_OPERATE_CODE     OUT NUMBER
      )
is
BEGIN
  INSERT
  INTO CA_NETWORK_PROCESS
    (
    
   
      USER_ID ,
      COMMIT_TIME ,
      CONTACT_TEL ,
      BREAKDOWN_TYPE,
      CONTACT_MOBILE ,
      BREAKDOWN_DESC ,
      BREAKDOWN_ADDRESS ,
     
      CONTACT_MAN
    )
    VALUES
    (
   
      p_USER_ID ,
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi'),
      p_CONTACT_TEL ,
     p_BREAKDOWN_TYPE,
      p_CONTACT_MOBILE ,
      p_BREAKDOWN_DESC ,
      p_BREAKDOWN_ADDRESS ,
      
      p_CONTACT_MAN
    );
    
    COMMIT;
    OP_OPERATE_CODE:=1;
    
  EXCEPTION
  WHEN OTHERS THEN
    OP_OPERATE_CODE:=-1;
  

END;
-- update
PROCEDURE upd
  (
    p_REC_ID            IN CA_NETWORK_PROCESS.REC_ID%type ,
    p_PROCESS_STATUS_ID IN CA_NETWORK_PROCESS.PROCESS_STATUS_ID%type DEFAULT NULL ,
    p_USER_ID           IN CA_NETWORK_PROCESS.USER_ID%type DEFAULT NULL ,
    p_COMMIT_TIME       IN CA_NETWORK_PROCESS.COMMIT_TIME%type DEFAULT NULL ,
    p_PROCESS_TIME      IN CA_NETWORK_PROCESS.PROCESS_TIME%type ,
    p_CONTACT_TEL       IN CA_NETWORK_PROCESS.CONTACT_TEL%type DEFAULT NULL ,
    p_PROCESS_ANALYSIS  IN CA_NETWORK_PROCESS.PROCESS_ANALYSIS%type DEFAULT NULL ,
    p_CONTACT_MOBILE    IN CA_NETWORK_PROCESS.CONTACT_MOBILE%type DEFAULT NULL ,
    p_BREAKDOWN_DESC    IN CA_NETWORK_PROCESS.BREAKDOWN_DESC%type ,
    p_BREAKDOWN_ADDRESS IN CA_NETWORK_PROCESS.BREAKDOWN_ADDRESS%type ,
    p_CONTACT_MAN       IN CA_NETWORK_PROCESS.CONTACT_MAN%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_NETWORK_PROCESS
  SET PROCESS_STATUS_ID = p_PROCESS_STATUS_ID ,
    USER_ID             = p_USER_ID ,
    COMMIT_TIME         = p_COMMIT_TIME ,
    PROCESS_TIME        = p_PROCESS_TIME ,
    CONTACT_TEL         = p_CONTACT_TEL ,
    PROCESS_ANALYSIS    = p_PROCESS_ANALYSIS ,
    CONTACT_MOBILE      = p_CONTACT_MOBILE ,
    BREAKDOWN_DESC      = p_BREAKDOWN_DESC ,
    BREAKDOWN_ADDRESS   = p_BREAKDOWN_ADDRESS ,
    CONTACT_MAN         = p_CONTACT_MAN
  WHERE REC_ID          = p_REC_ID;
END;
-- del
PROCEDURE del(
    p_REC_ID IN CA_NETWORK_PROCESS.REC_ID%type )
IS
BEGIN
  DELETE FROM CA_NETWORK_PROCESS WHERE REC_ID = p_REC_ID;
END;

--获取处理状态
FUNCTION GET_PROCESS_STATUS(
	IP_STATUS_ID IN NUMBER
)
RETURN NVARCHAR2
is
BEGIN
	CASE  IP_STATUS_ID
		WHEN  1  THEN
			RETURN '新提交';
		WHEN  2	 THEN
			RETURN '处理中';
		WHEN  3	 THEN
			RETURN '已处理';
	END CASE;
	RETURN '未处理';
END ;

---分页获取数据
PROCEDURE PAGE_NETWORK(
    IP_PAGE_INDEX IN NUMBER,--索引
    IP_PAGE_SIZE  IN NUMBER,--页面大小
    IP_MERCHANT_ID IN CA_SIMPLE_FOOD.MERCHANT_ID%TYPE,--商家ID
    SELECT_RESULT OUT SYS_REFCURSOR,--查询结果
    OP_ROWCOUNT OUT NUMBER ,--数据量
	OP_CODE OUT NUMBER,---操作代码
    OP_MSG OUT NVARCHAR2
)
AS
	e_user_not_exist_exception exception;--用户不存在
	e_user_lock_exception exception;--用户被锁定
	e_lack_permission_exception exception;--用户权限缺失
	
	v_user_type number(1,0)   default 0;
	v_user_count number(1,0)  default 0;
	v_lock_status number(1,0) default 0;
	V_CUR_PAGE NUMBER;
BEGIN
	select count(*) into v_user_count  from CA_MERCHANT	where login_id = IP_MERCHANT_ID;
	if v_user_count=0 then
		raise e_user_not_exist_exception;
	end if;
		
	select STATUS,MERCHANT_TYPE into v_lock_status,v_user_type from CA_MERCHANT	where login_id = IP_MERCHANT_ID;
	if v_lock_status=0 then
		raise e_user_lock_exception;
	end if;
	
	V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	if v_user_type <> 5 then
		raise e_lack_permission_exception;
	end if;
	
	
	begin
	--rowcount
	
	SELECT COUNT(*) INTO OP_ROWCOUNT FROM v_network_process;
	--end;
	
	--datas
	OPEN SELECT_RESULT FOR
	  SELECT * FROM ( 
	   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
		SELECT * FROM 
			v_network_process
		
		ORDER BY commit_time DESC	
		  

	   ) T)
	  )
	  WHERE
	  RN >= (V_CUR_PAGE + 1) AND 
	  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);
		
	--end;
	OP_CODE:=1;
	end;
exception
	when 	e_user_not_exist_exception THEN
	
			begin
				OP_MSG:='用户不存在';
				OP_CODE:=-1;
			end;			
	when 	e_user_lock_exception THEN
			begin
				OP_MSG:='用户被锁定';
				OP_CODE:=-2;
        
        
			end;
	when 	e_lack_permission_exception THEN
		begin
				OP_MSG:='用户缺失权限';
				OP_CODE:=-3;
		end;
	when 	no_data_found THEN
		begin
				OP_MSG:='没有找到数据';
				OP_CODE:=-4;
		end;
	when 	others THEN
		begin
				OP_CODE:=-5;
				OP_MSG:='操作失败{code='||sqlcode||' msg='||sqlerrm||'}';
		end;
END;

PROCEDURE SEL_VIEW(
IP_REC_ID IN NUMBER,
OP_SEL_RESULT OUT SYS_REFCURSOR,
OP_CODE OUT NUMBER,
OP_MSG  OUT NVARCHAR2--更新消息
)
AS
	
BEGIN
	OPEN OP_SEL_RESULT FOR
		SELECT 
			* 
		FROM 
			v_network_process
		WHERE 
		REC_ID =IP_REC_ID;
	
	OP_CODE:=1;
	OP_MSG:='';
	
	
EXCEPTION 
WHEN OTHERS THEN
	BEGIN
		
		OP_CODE:=-1;
		OP_MSG:='获取数据失败{code='||sqlcode||' msg='||sqlerrm||'}';
	END;
		
END;

PROCEDURE DELETE_V2(
	IP_RECID IN NUMBER,
	IP_CODE OUT NUMBER,
	OP_MSG  OUT NVARCHAR2
)
AS
BEGIN
	
	DELETE FROM CA_NETWORK_PROCESS WHERE REC_ID = IP_RECID;
	COMMIT;
	IP_CODE:=1;
	
EXCEPTION 
	WHEN OTHERS THEN
		BEGIN
      ROLLBACK;	
      IP_CODE:=-1;	
		 OP_MSG:='删除失败{code='||sqlcode||' msg='||sqlerrm||'}';
		END;
	
	
END;

PROCEDURE MARK_STATUS(
	IP_REC_ID IN NUMBER,
	IP_STATUS_ID IN NUMBER,
	OP_CODE OUT NUMBER,
	OP_MSG OUT NVARCHAR2

)
AS

BEGIN
  
	UPDATE CA_NETWORK_PROCESS
	SET 
		PROCESS_STATUS_ID = IP_STATUS_ID 
		
	WHERE 
		REC_ID          = IP_REC_ID;
	COMMIT;
	OP_CODE:=1;
	
EXCEPTION 
	WHEN OTHERS THEN
		BEGIN
		 ROLLBACK;	
		 OP_CODE:=-1;	
		 OP_MSG:='标记失败{code='||sqlcode||' msg='||sqlerrm||'}';
		END;
		
END;


PROCEDURE FINISH(
	IP_REC_ID  IN NUMBER,
	IP_PROCESS_MAN IN NVARCHAR2,--处理人
	IP_PROCESS_ANALYSIS CA_NETWORK_PROCESS.PROCESS_ANALYSIS%TYPE,
	OP_CODE OUT NUMBER,
	OP_MSG OUT NVARCHAR2
)AS
e_duplicate_commit exception;
v_status_id number(1,0);
BEGIN
    
   select nvl(PROCESS_STATUS_ID,0)  into v_status_id from CA_NETWORK_PROCESS WHERE REC_ID          = IP_REC_ID;
   if v_status_id= 3 then
    raise e_duplicate_commit;
   end if;
   
	 UPDATE CA_NETWORK_PROCESS
	 SET  
		PROCESS_TIME         = TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mm') ,
    PROCESS_STATUS_ID = 3,
     PROCESS_ANALYSIS    = IP_PROCESS_ANALYSIS ,
		PROCESS_MAN			 = IP_PROCESS_MAN
	 WHERE REC_ID          = IP_REC_ID;
	 COMMIT;
	 OP_CODE:=1;
	 
	 
	 
	EXCEPTION 
  when e_duplicate_commit then
    	BEGIN
       ROLLBACK;	
       OP_CODE:=-1;	
       OP_MSG:='操作被拒绝,您已经处理过该维修';
		END;
  
	WHEN OTHERS THEN
		BEGIN
		 ROLLBACK;	
		 OP_CODE:=-1;	
		 OP_MSG:='操作失败{code='||sqlcode||' msg='||sqlerrm||'}';
		END;	
	
END;



PROCEDURE SEL_VIEW_V2(
IP_REC_ID IN NUMBER,
IP_MERCHANT_TYPE IN NUMBER,
OP_SEL_RESULT OUT SYS_REFCURSOR,
OP_CODE OUT NUMBER,
OP_MSG  OUT NVARCHAR2--更新消息
)
AS
	v_user_type NUMBER(1,0);
	e_lack_permission exception;
BEGIN

	if v_user_type =5 then
		OPEN OP_SEL_RESULT FOR
		SELECT 
			* 
		FROM 
			v_network_process
		WHERE 
			REC_ID =IP_REC_ID
		AND
			BREAKDOWN_TYPE = 1
			;
	elsif v_user_type =6 then
		OPEN OP_SEL_RESULT FOR
		SELECT 
			* 
		FROM 
			v_network_process
		WHERE 
			REC_ID =IP_REC_ID
		AND
			BREAKDOWN_TYPE = 2
			;
	else
		raise e_lack_permission;
	end if;

	
	
	OP_CODE:=1;
	OP_MSG:='';
	
	
EXCEPTION 
WHEN e_lack_permission THEN
	BEGIN
		
		OP_CODE:=-1;
		OP_MSG:='对不起,您没有权限访问该数据';
	END;
  
WHEN OTHERS THEN
	BEGIN
		
		OP_CODE:=-1;
		OP_MSG:='获取数据失败{code='||sqlcode||' msg='||sqlerrm||'}';
	END;
		
END;


PROCEDURE PAGE_NETWORKV2(
    IP_PAGE_INDEX IN NUMBER,--索引
    IP_PAGE_SIZE  IN NUMBER,--页面大小
    IP_MERCHANT_ID IN CA_SIMPLE_FOOD.MERCHANT_ID%TYPE,--商家ID
    SELECT_RESULT OUT SYS_REFCURSOR,--查询结果
    OP_ROWCOUNT OUT NUMBER ,--数据量
	OP_CODE OUT NUMBER,---操作代码
    OP_MSG OUT NVARCHAR2
)
AS
	e_user_not_exist_exception exception;--用户不存在
	e_user_lock_exception exception;--用户被锁定
	e_lack_permission_exception exception;--用户权限缺失
	
	v_user_type number(1,0)   default 0;
	v_user_count number(1,0)  default 0;
	v_lock_status number(1,0) default 0;
	V_CUR_PAGE NUMBER;
BEGIN
	select count(*) into v_user_count  from CA_MERCHANT	where login_id = IP_MERCHANT_ID;
	if v_user_count=0 then
		raise e_user_not_exist_exception;
	end if;
		
	select STATUS,MERCHANT_TYPE into v_lock_status,v_user_type from CA_MERCHANT	where login_id = IP_MERCHANT_ID;
	if v_lock_status=0 then
		raise e_user_lock_exception;
	end if;
	
	V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	if v_user_type =5 then
	begin
		--rowcount
		
		SELECT COUNT(*) INTO OP_ROWCOUNT FROM v_network_process where BREAKDOWN_TYPE = 1;
		--end;
		
		--datas
		OPEN SELECT_RESULT FOR
		  SELECT * FROM ( 
		   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
			SELECT * FROM 
				v_network_process
					where BREAKDOWN_TYPE = 1
			ORDER BY commit_time DESC	
			  

		   ) T)
		  )
		  WHERE
		  RN >= (V_CUR_PAGE + 1) AND 
		  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);
		  
	  end;
	elsif  v_user_type =6 then
		
	begin
		--rowcount
	
		SELECT COUNT(*) INTO OP_ROWCOUNT FROM v_network_process where BREAKDOWN_TYPE = 2;
		--end;
		
		--datas
		OPEN SELECT_RESULT FOR
		  SELECT * FROM ( 
		   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
			SELECT * FROM 
				v_network_process
					where BREAKDOWN_TYPE = 2
			ORDER BY commit_time DESC	
			  

		   ) T)
		  )
		  WHERE
		  RN >= (V_CUR_PAGE + 1) AND 
		  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);
		
		end;
		else 
			raise e_lack_permission_exception;
		end if;
	
	
	 
	OP_CODE:=1;
	 
exception
	when 	e_user_not_exist_exception THEN
	
			begin
				OP_MSG:='用户不存在';
				OP_CODE:=-1;
			end;			
	when 	e_user_lock_exception THEN
			begin
				OP_MSG:='用户被锁定';
				OP_CODE:=-2;
			end;
	when 	e_lack_permission_exception THEN
		begin
				OP_MSG:='用户缺失权限';
				OP_CODE:=-3;
		end;
	when 	no_data_found THEN
		begin
				OP_MSG:='没有找到数据';
				OP_CODE:=-4;
		end;
	when 	others THEN
		begin
				OP_CODE:=-5;
				OP_MSG:='操作失败{code='||sqlcode||' msg='||sqlerrm||'}';
		end;
END;

END CA_NETWORK_PROCESS_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_ORDER_GOODS_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_ORDER_GOODS_TAPI" 
IS
  -- insert
PROCEDURE ins(
    --p_REC_ID       IN CA_ORDER_GOODS.REC_ID%type ,
    p_ORDER_ID     IN CA_ORDER_GOODS.ORDER_ID%type DEFAULT NULL ,
    p_GOODS_NUMBER IN CA_ORDER_GOODS.GOODS_NUMBER%type DEFAULT NULL ,
    p_GOODS_NAME   IN CA_ORDER_GOODS.GOODS_NAME%type DEFAULT NULL ,
    p_GOODS_ID     IN CA_ORDER_GOODS.GOODS_ID%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_ORDER_GOODS
    (
      --REC_ID ,
      ORDER_ID,
      GOODS_NUMBER ,
      GOODS_NAME ,
      GOODS_ID
    )
    VALUES
    (
      --p_REC_ID ,
      p_ORDER_ID ,
      p_GOODS_NUMBER ,
      p_GOODS_NAME ,
      p_GOODS_ID
    );
END;
-- update
PROCEDURE upd
  (
    p_REC_ID       IN CA_ORDER_GOODS.REC_ID%type ,
    p_ORDER_ID     IN CA_ORDER_GOODS.ORDER_ID%type DEFAULT NULL ,
    p_GOODS_NUMBER IN CA_ORDER_GOODS.GOODS_NUMBER%type DEFAULT NULL ,
    p_GOODS_NAME   IN CA_ORDER_GOODS.GOODS_NAME%type DEFAULT NULL ,
    p_GOODS_ID     IN CA_ORDER_GOODS.GOODS_ID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_ORDER_GOODS
  SET ORDER_ID   = p_ORDER_ID ,
    GOODS_NUMBER = p_GOODS_NUMBER ,
    GOODS_NAME   = p_GOODS_NAME ,
    GOODS_ID     = p_GOODS_ID
  WHERE REC_ID   = p_REC_ID;
END;
-- del
PROCEDURE del(
    p_REC_ID IN CA_ORDER_GOODS.REC_ID%type )
IS
BEGIN
  DELETE FROM CA_ORDER_GOODS WHERE REC_ID = p_REC_ID;
END;
END CA_ORDER_GOODS_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_ORDER_INFO_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_ORDER_INFO_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_USER_MARK        IN CA_ORDER_INFO.USER_MARK%type DEFAULT NULL ,--用户对本次订单的评价
    p_ORDER_STATUS     IN CA_ORDER_INFO.ORDER_STATUS%type DEFAULT NULL ,--订单当前状态
    p_GOODS_AMOUNT     IN CA_ORDER_INFO.GOODS_AMOUNT%type DEFAULT NULL ,--订单总价
    p_USER_ID          IN CA_ORDER_INFO.USER_ID%type DEFAULT NULL ,--用户ID
    p_MERCHANT_NOTE    IN CA_ORDER_INFO.MERCHANT_NOTE%type DEFAULT NULL ,--商家评价，忽略
    p_SHIPPING_FEE     IN CA_ORDER_INFO.SHIPPING_FEE%type DEFAULT NULL ,--配送费用
    p_MERCHANT_MARK    IN CA_ORDER_INFO.MERCHANT_MARK%type DEFAULT NULL ,--商家评价
    p_DELIVERY_ADDRESS IN CA_ORDER_INFO.DELIVERY_ADDRESS%type ,--配送地址
    p_CONFIRM_TIME     IN CA_ORDER_INFO.CONFIRM_TIME%type DEFAULT NULL ,--确定收货时间
    p_ADD_TIME         IN CA_ORDER_INFO.ADD_TIME%type DEFAULT NULL ,--订单创建时间
    p_USER_NOTE        IN CA_ORDER_INFO.USER_NOTE%type DEFAULT NULL ,---用户备注，雷伊忽略
  --  p_ORDER_ID         IN CA_ORDER_INFO.ORDER_ID%type ,
    p_MOBILE           IN CA_ORDER_INFO.MOBILE%type ,--移动电话
    p_TEL              IN CA_ORDER_INFO.TEL%type DEFAULT NULL ,--电话
    p_GOODS_ID         IN CA_ORDER_INFO.GOODS_ID%type DEFAULT NULL ,--货物ID
    p_MERCHANT_ID      IN CA_ORDER_INFO.MERCHANT_ID%type ,--商家ID
    p_CONSIGNEE        IN CA_ORDER_INFO.CONSIGNEE%type DEFAULT NULL,--收货人姓名
    op_ins_code out number
    )
IS
  user_lock_exception exception;
  t_user_lock_status number(1,0);
BEGIN
   select STATUS into t_user_lock_status from common_user where login_id = p_USER_ID;
   if  t_user_lock_status = -1 then
    raise user_lock_exception;
   end if;
    
  INSERT
  INTO CA_ORDER_INFO
    (
      USER_MARK ,
      ORDER_STATUS ,
      GOODS_AMOUNT ,
      USER_ID ,
      MERCHANT_NOTE ,
      SHIPPING_FEE ,
      MERCHANT_MARK ,
      DELIVERY_ADDRESS ,
      CONFIRM_TIME ,
      ADD_TIME ,
      USER_NOTE ,
       MOBILE ,
      TEL ,
      GOODS_ID ,
      MERCHANT_ID ,
      CONSIGNEE
    )
    VALUES
    (
      p_USER_MARK ,
      p_ORDER_STATUS ,
      p_GOODS_AMOUNT ,
      p_USER_ID ,
      p_MERCHANT_NOTE ,
      p_SHIPPING_FEE ,
      p_MERCHANT_MARK ,
      p_DELIVERY_ADDRESS ,
      p_CONFIRM_TIME ,
      p_ADD_TIME ,
      p_USER_NOTE ,
     -- p_ORDER_ID ,
      p_MOBILE ,
      p_TEL ,
      p_GOODS_ID ,
      p_MERCHANT_ID ,
      p_CONSIGNEE
    );
    op_ins_code:=1;
    
exception

when no_data_found then
  op_ins_code :=0;
when user_lock_exception then
  op_ins_code := -2;
when others then
  op_ins_code:=-1;
  
END;
-- update
PROCEDURE upd
  (
    p_USER_MARK        IN CA_ORDER_INFO.USER_MARK%type DEFAULT NULL ,
    p_ORDER_STATUS     IN CA_ORDER_INFO.ORDER_STATUS%type DEFAULT NULL ,
    p_GOODS_AMOUNT     IN CA_ORDER_INFO.GOODS_AMOUNT%type DEFAULT NULL ,
    p_USER_ID          IN CA_ORDER_INFO.USER_ID%type DEFAULT NULL ,
    p_MERCHANT_NOTE    IN CA_ORDER_INFO.MERCHANT_NOTE%type DEFAULT NULL ,
    p_SHIPPING_FEE     IN CA_ORDER_INFO.SHIPPING_FEE%type DEFAULT NULL ,
    p_MERCHANT_MARK    IN CA_ORDER_INFO.MERCHANT_MARK%type DEFAULT NULL ,
    p_DELIVERY_ADDRESS IN CA_ORDER_INFO.DELIVERY_ADDRESS%type ,
    p_CONFIRM_TIME     IN CA_ORDER_INFO.CONFIRM_TIME%type DEFAULT NULL ,
    p_ADD_TIME         IN CA_ORDER_INFO.ADD_TIME%type DEFAULT NULL ,
    p_USER_NOTE        IN CA_ORDER_INFO.USER_NOTE%type DEFAULT NULL ,
    p_ORDER_ID         IN CA_ORDER_INFO.ORDER_ID%type ,
    p_MOBILE           IN CA_ORDER_INFO.MOBILE%type ,
    p_TEL              IN CA_ORDER_INFO.TEL%type DEFAULT NULL ,
    p_GOODS_ID         IN CA_ORDER_INFO.GOODS_ID%type DEFAULT NULL ,
    p_MERCHANT_ID      IN CA_ORDER_INFO.MERCHANT_ID%type ,
    p_CONSIGNEE        IN CA_ORDER_INFO.CONSIGNEE%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_ORDER_INFO
  SET USER_MARK      = p_USER_MARK ,
    ORDER_STATUS     = p_ORDER_STATUS ,
    GOODS_AMOUNT     = p_GOODS_AMOUNT ,
    USER_ID          = p_USER_ID ,
    MERCHANT_NOTE    = p_MERCHANT_NOTE ,
    SHIPPING_FEE     = p_SHIPPING_FEE ,
    MERCHANT_MARK    = p_MERCHANT_MARK ,
    DELIVERY_ADDRESS = p_DELIVERY_ADDRESS ,
    CONFIRM_TIME     = p_CONFIRM_TIME ,
    ADD_TIME         = p_ADD_TIME ,
    USER_NOTE        = p_USER_NOTE ,
    MOBILE           = p_MOBILE ,
    TEL              = p_TEL ,
    GOODS_ID         = p_GOODS_ID ,
    MERCHANT_ID      = p_MERCHANT_ID ,
    CONSIGNEE        = p_CONSIGNEE
  WHERE ORDER_ID     = p_ORDER_ID;
END;
-- del
PROCEDURE del(
    p_ORDER_ID IN CA_ORDER_INFO.ORDER_ID%type )
IS
BEGIN
  DELETE FROM CA_ORDER_INFO WHERE ORDER_ID = p_ORDER_ID;
END;

  procedure ins_v2(ip_data in nvarchar2, op_ins_code out number )
  is
    --用户权限判断
    user_lock_exception exception;
    t_user_lock_status number(1,0);
  
    obj json;
    order_data_list json_list;
    obj_values json_value;
    t_iterator number(2,0);--迭代变量
    t_amount number(10,2);
    t_userid common_user.login_id%type;
    t_delivery_address ca_order_info.delivery_address%type;
    t_mobile ca_order_info.mobile%type;
    t_tel ca_order_info.tel%type;
    t_goods_id  ca_simple_food.record_id%type;
    t_merchat_id ca_merchant.login_id%type;
    t_consignee ca_order_info.consignee%type;
    t_goods_number number(2,0);
    t_goods_name ca_simple_food.food_name%type;
    t_order_id ca_order_info.goods_id%type;
  begin
    obj :=json(ip_data);
    
    --获取数组对象
  order_data_list := obj.get_values();
 
 -- order_data_list.print;
  obj_values:=order_data_list.get(1);
  order_data_list:=json_list(obj_values.to_char);
--  order_data_list.get(1).print;
   --数据迭代
  t_iterator :=1;
  for t_iterator in 1..order_data_list.count 
  loop
    --数据插入
  --  t_amount:=order_data_list.get(t_iterator).get('amount').get_number;
  obj_values:=order_data_list.GET(t_iterator);
  obj:=json(obj_values.to_char);
    
    t_amount:=obj.get('amount').get_number;
    t_userid:=obj.get('userid').get_string;
    t_delivery_address:=obj.get('delivery_address').get_string;
    t_mobile:=obj.get('mobile').get_string;
    t_tel:=obj.get('tel').get_string;
    t_goods_id:=obj.get('goods_id').get_number;
    t_merchat_id:=obj.get('merchat_id').get_string;
    t_consignee:=obj.get('consignee').get_string;
    t_goods_number:=obj.get('goods_number').get_number;
    t_goods_name:=obj.get('goods_name').get_string;
    
    /*=====================DEBUG======================================*/
    dbms_output.put_line('
    t_iterator=['||t_iterator||'],
    amount['||t_amount ||'],
    userid['||t_userid||'],
    delivery_address['||t_delivery_address||'],
    mobile['||t_mobile||'],
    tel['||t_tel||'],
    goods_id['||t_goods_id||'],
    merchat_id['||t_merchat_id||'],
    consignee['||t_consignee||'],
    goods_number['||t_goods_number||'],
    goods_name['||t_goods_name||']
    ');
    
    /*============================INS DATA===============================*/
    BEGIN
      ---订单表
     t_order_id := CA_SEQ_ORDER_INFO.nextval; 
     INSERT
     INTO CA_ORDER_INFO
    (
    ORDER_ID,
      GOODS_AMOUNT ,
      USER_ID ,
      DELIVERY_ADDRESS ,
      ADD_TIME ,
      MOBILE ,
      TEL ,
      GOODS_ID ,
      MERCHANT_ID ,
      CONSIGNEE
    )
    VALUES
    (
      t_order_id,
      t_amount ,
      t_userid ,
      t_delivery_address ,
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi'),
      t_mobile ,
      t_tel ,
      t_goods_id ,
      t_merchat_id ,
      t_consignee
    );
    
    /*=============订单货物表========*/
    CA_ORDER_GOODS_tapi.ins(
        t_order_id,
        t_goods_number,
        t_goods_name,
        t_goods_id
    );
    --更新商家最新消息表
    update  ca_merchant 
    set new_order =new_order+1
    where login_id = t_merchat_id;
    
    --删除购物车
    delete from CA_CART 
    where 
    USER_ID = t_userid 
    and GOODS_ID = t_goods_id;
    
    END;
    
    
  end loop;
    
    COMMIT;
    op_ins_code:=1;
    
  exception 
  when no_data_found then
  ROLLBACK;
  op_ins_code :=0;
  when user_lock_exception then
   ROLLBACK;
  op_ins_code := -2;
  when others then
   ROLLBACK;
  op_ins_code:=-1;
    
  end;



/*================================================================================================================*/
PROCEDURE SEL_ORDER_BY_USER(
    IP_PAGE_INDEX IN NUMBER,
    IP_PAGE_SIZE IN NUMBER,
 
    IP_USER_ID IN NVARCHAR2,
    OP_SELECT_RESULT OUT SYS_REFCURSOR,
    OP_OPERATE_CODE OUT NUMBER
  )
  IS
      user_lock_exception  exception;
      user_not_exist exception ;
      t_lock_status number(1,0);
      t_user_count number(1,0);
      V_CUR_PAGE NUMBER;
  BEGIN
     --permisson check
    select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
     V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
    
     OPEN OP_SELECT_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
 
      SELECT * FROM CA_ORDER_INFO LEFT JOIN
      CA_ORDER_GOODS ON CA_ORDER_INFO.GOODS_ID = CA_ORDER_GOODS.ORDER_ID
      WHERE USER_ID = IP_USER_ID
      ORDER BY ADD_TIME DESC

   ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);

 OP_OPERATE_CODE:=1;
    
    
    exception
  when user_not_exist then
    OP_OPERATE_CODE:=-2;
   when   user_lock_exception then
    OP_OPERATE_CODE:=-3;
  WHEN NO_DATA_FOUND THEN
    OP_OPERATE_CODE:=0;
  when others then
    OP_OPERATE_CODE:=-1; 
END ;
  
  
 


PROCEDURE WEB_SEL_ORDER_BY_USER(
    IP_PAGE_INDEX IN NUMBER,
    IP_PAGE_SIZE IN NUMBER,
 
    IP_USER_ID IN NVARCHAR2,
    OP_SELECT_RESULT OUT SYS_REFCURSOR,
    OP_ROW_COUNT OUT NUMBER,
    OP_OPERATE_CODE OUT NUMBER
  )
  IS
  user_not_exist_exception exception;
  user_lock_exception exception;
  t_user_count number(1,0);
  t_user_lock_status number(1,0);
  V_CUR_PAGE NUMBER;
BEGIN
    select count(*) into t_user_count from CA_MERCHANT where login_id = IP_USER_ID;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  
  
  
  --检测用户是否被锁定
  select status into t_user_lock_status from  CA_MERCHANT where LOGIN_ID = IP_USER_ID;
  if t_user_lock_status<>1 then
    raise user_lock_exception;
  end if;
    
    
     V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
    
      SELECT 
  COUNT(*) INTO OP_ROW_COUNT
FROM CA_ORDER_INFO LEFT JOIN
      CA_ORDER_GOODS ON CA_ORDER_INFO.GOODS_ID = CA_ORDER_GOODS.ORDER_ID
      WHERE merchant_id = IP_USER_ID;
     OPEN OP_SELECT_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
 
    SELECT 
  CA_ORDER_INFO.ORDER_ID REC_ID,
  TO_CHAR(CA_ORDER_INFO.ORDER_ID,'09999999') AS ORDER_ID,
  nvl(USER_ID, '无') USER_ID ,
  nvl(CONSIGNEE, '无') CONSIGNEE,
  nvl(TEL, '无') TEL,
  nvl(MOBILE, '无') MOBILE,
  to_char(nvl(GOODS_AMOUNT, '0'),'L999.00') GOODS_AMOUNT,
  nvl(ADD_TIME, '无') ADD_TIME,
  nvl(GOODS_NUMBER, '0') GOODS_NUMBER,
  nvl(GOODS_NAME, '无') GOODS_NAME,
  ORDER_STATUS ,
  system.CA_ORDER_INFO_tapi.GET_ORDER_STATUS(ORDER_STATUS) as STATUS_NAME
FROM CA_ORDER_INFO LEFT JOIN
      CA_ORDER_GOODS ON CA_ORDER_INFO.GOODS_ID = CA_ORDER_GOODS.ORDER_ID
      WHERE merchant_id = IP_USER_ID
      ORDER BY ADD_TIME DESC

   ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);

 OP_OPERATE_CODE:=1;
    
    
    exception
 
   when   user_lock_exception then
    OP_OPERATE_CODE:=-3;
  WHEN NO_DATA_FOUND THEN
    OP_OPERATE_CODE:=0;
  when others then
    OP_OPERATE_CODE:=-1; 
END ;


 PROCEDURE SEL_MERCHANT_ORDER_LIST(
    IP_PAGE_INDEX IN NUMBER,
    IP_PAGE_SIZE IN NUMBER,
    IP_USER_ID IN NVARCHAR2,
    OP_SELECT_RESULT OUT SYS_REFCURSOR,
    OP_OPERATE_CODE OUT NUMBER
  )
  IS
  user_not_exist_exception exception;
  user_lock_exception exception;
  t_user_count number(1,0);
  t_user_lock_status number(1,0);
   V_CUR_PAGE NUMBER;
  BEGIN
    select count(*) into t_user_count from CA_MERCHANT where login_id = IP_USER_ID;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  
  
  
  --检测用户是否被锁定
  select status into t_user_lock_status from  CA_MERCHANT where LOGIN_ID = IP_USER_ID;
  if t_user_lock_status<>1 then
    raise user_lock_exception;
  end if;
    
  
   V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
    
     OPEN OP_SELECT_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
 
     select  
    CA_ORDER_INFO.ORDER_ID,
    CA_ORDER_INFO.CONSIGNEE,
    CA_ORDER_INFO.USER_ID,
    CA_ORDER_INFO.TEL,
    
    CA_ORDER_INFO.MOBILE,
    CA_ORDER_INFO.GOODS_AMOUNT,
    CA_ORDER_INFO.ADD_TIME,
    CA_ORDER_INFO.DELIVERY_ADDRESS,
    
    CA_ORDER_INFO.ORDER_STATUS,
    CA_ORDER_GOODS.GOODS_NUMBER,
    CA_ORDER_GOODS.GOODS_NAME
 
  
  from CA_ORDER_INFO left join CA_ORDER_GOODS
  on ca_order_goods.order_id = CA_ORDER_INFO.order_id
  where MERCHANT_ID = IP_USER_ID
  ORDER BY ADD_TIME DESC


   ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);

 OP_OPERATE_CODE:=1;
  
   exception
  when user_not_exist_exception then
    OP_OPERATE_CODE:=-2;
     OPEN OP_SELECT_RESULT FOR
     SELECT '用户不存在' from dual;
   when   user_lock_exception then
    OP_OPERATE_CODE:=-3;
     OPEN OP_SELECT_RESULT FOR
    SELECT '用户被锁定' from dual;
  when others then
    OP_OPERATE_CODE:=-1; 
     OPEN OP_SELECT_RESULT FOR
     SELECT '发生异常' from dual;
  END;




FUNCTION GET_ORDER_STATUS(ip_status_id in number) RETURN NVARCHAR2
is
begin
   case ip_status_id
    when  1 then
     return '已提交';
    when 2 then
   return '已发货';
    when 3 then
   return '已收货';
   else
    return '错误状态';
   end case;
end;



END CA_ORDER_INFO_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_COMMON
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_COMMON" 

IS

  FUNCTION DATE_2_TIMESTAMP(IP_DATE IN DATE)
  RETURN NUMBER
  AS
  BEGIN
      return( (IP_DATE -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600);
  END DATE_2_TIMESTAMP; 
    /*===========================根据经纬度计算两点距离=======================*/
   FUNCTION GetDistance(lat1 number,
                        lng1 number,
                        lat2 number,
                        lng2 number) 
  RETURN NUMBER 
  as
      earth_padius number := 6378.137;
      radLat1      number := rad(lat1);
      radLat2      number := rad(lat2);
      a            number := radLat1 - radLat2;
      b            number := rad(lng1) - rad(lng2);
      s            number := 0;
    begin
    s := 2 *Asin(Sqrt(power(sin(a / 2), 2) +
                   cos(radLat1) * cos(radLat2) * power(sin(b / 2), 2)));
    s := s * earth_padius;
    s := Round(s * 10000) / 10000;
    return s;

  end GetDistance;
  
  FUNCTION RAD(d number) RETURN NUMBER
  is
    PI number :=3.141592625;
    
    begin 
    return  d* PI/180.0;
  end ;
END CA_PKG_COMMON;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_COMMON_USER
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_COMMON_USER" 
IS
  -- insert
PROCEDURE ins(
    p_LOGIN_ID         IN COMMON_USER.LOGIN_ID%type ,
    p_REGSTATUS        IN COMMON_USER.REGSTATUS%type DEFAULT NULL ,
    p_CHANNEL_ID       IN COMMON_USER.CHANNEL_ID%type DEFAULT NULL ,
    p_GROUPID          IN COMMON_USER.GROUPID%type DEFAULT NULL ,
    p_USER_APP_ID      IN COMMON_USER.USER_APP_ID%type DEFAULT NULL ,
    p_USER_TYPE        IN COMMON_USER.USER_TYPE%type DEFAULT NULL ,
    p_STATUS           IN COMMON_USER.STATUS%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN COMMON_USER.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_NICKNAME         IN COMMON_USER.NICKNAME%type DEFAULT NULL ,
    p_USER_MOBILE_TYPE IN COMMON_USER.USER_MOBILE_TYPE%type DEFAULT NULL ,
    p_ALLOWADMINCP     IN COMMON_USER.ALLOWADMINCP%type DEFAULT NULL ,
   -- p_RECORD_ID        IN COMMON_USER.RECORD_ID%type ,
    p_IDNUMBER         IN COMMON_USER.IDNUMBER%type DEFAULT NULL ,
    p_USER_TAGS        IN COMMON_USER.USER_TAGS%type DEFAULT NULL ,
    p_NEWPROMPT        IN COMMON_USER.NEWPROMPT%type DEFAULT NULL ,
    p_NEWPM            IN COMMON_USER.NEWPM%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO COMMON_USER
    (
      LOGIN_ID ,
      REGSTATUS ,
      CHANNEL_ID ,
      GROUPID ,
      USER_APP_ID ,
      USER_TYPE ,
      STATUS ,
      ENCRYPTPASSWORD ,
      NICKNAME ,
      USER_MOBILE_TYPE ,
      ALLOWADMINCP ,
   --   RECORD_ID ,
      IDNUMBER ,
      USER_TAGS ,
      NEWPROMPT ,
      NEWPM
    )
    VALUES
    (
      p_LOGIN_ID ,
      p_REGSTATUS ,
      p_CHANNEL_ID ,
      p_GROUPID ,
      p_USER_APP_ID ,
      p_USER_TYPE ,
      p_STATUS ,
      p_ENCRYPTPASSWORD ,
      p_NICKNAME ,
      p_USER_MOBILE_TYPE ,
      p_ALLOWADMINCP ,
     -- p_RECORD_ID ,
      p_IDNUMBER ,
      p_USER_TAGS ,
      p_NEWPROMPT ,
      p_NEWPM
    );
END;
-- update
PROCEDURE upd
  (
    p_LOGIN_ID         IN COMMON_USER.LOGIN_ID%type ,
    p_REGSTATUS        IN COMMON_USER.REGSTATUS%type DEFAULT NULL ,
    p_CHANNEL_ID       IN COMMON_USER.CHANNEL_ID%type DEFAULT NULL ,
    p_GROUPID          IN COMMON_USER.GROUPID%type DEFAULT NULL ,
    p_USER_APP_ID      IN COMMON_USER.USER_APP_ID%type DEFAULT NULL ,
    p_USER_TYPE        IN COMMON_USER.USER_TYPE%type DEFAULT NULL ,
    p_STATUS           IN COMMON_USER.STATUS%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN COMMON_USER.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_NICKNAME         IN COMMON_USER.NICKNAME%type DEFAULT NULL ,
    p_USER_MOBILE_TYPE IN COMMON_USER.USER_MOBILE_TYPE%type DEFAULT NULL ,
    p_ALLOWADMINCP     IN COMMON_USER.ALLOWADMINCP%type DEFAULT NULL ,
    p_RECORD_ID        IN COMMON_USER.RECORD_ID%type ,
    p_IDNUMBER         IN COMMON_USER.IDNUMBER%type DEFAULT NULL ,
    p_USER_TAGS        IN COMMON_USER.USER_TAGS%type DEFAULT NULL ,
    p_NEWPROMPT        IN COMMON_USER.NEWPROMPT%type DEFAULT NULL ,
    p_NEWPM            IN COMMON_USER.NEWPM%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE COMMON_USER
  SET REGSTATUS      = p_REGSTATUS ,
    CHANNEL_ID       = p_CHANNEL_ID ,
    GROUPID          = p_GROUPID ,
    USER_APP_ID      = p_USER_APP_ID ,
    USER_TYPE        = p_USER_TYPE ,
    STATUS           = p_STATUS ,
    ENCRYPTPASSWORD  = p_ENCRYPTPASSWORD ,
    NICKNAME         = p_NICKNAME ,
    USER_MOBILE_TYPE = p_USER_MOBILE_TYPE ,
    ALLOWADMINCP     = p_ALLOWADMINCP ,
    RECORD_ID        = p_RECORD_ID ,
    IDNUMBER         = p_IDNUMBER ,
    USER_TAGS        = p_USER_TAGS ,
    NEWPROMPT        = p_NEWPROMPT ,
    NEWPM            = p_NEWPM
  WHERE LOGIN_ID     = p_LOGIN_ID;
END;
-- del
PROCEDURE del(
    p_LOGIN_ID IN COMMON_USER.LOGIN_ID%type )
IS
BEGIN
  DELETE FROM COMMON_USER WHERE LOGIN_ID = p_LOGIN_ID;
END;

/*=========================================查找用户====================================================*/     
  PROCEDURE SEL_BY_LOGINUD (
    IP_LOGIN_ID COMMON_USER.LOGIN_ID%type ,
    OP_OPERATE_CODE OUT NUMBER,
    OP_SEL_RESULT OUT SYS_REFCURSOR
  )
  AS
  
  BEGIN
    OPEN OP_SEL_RESULT FOR 
      SELECT * FROM 
      COMMON_USER LEFT JOIN COMMON_USER_PROFILE 
      ON COMMON_USER.LOGIN_ID = COMMON_USER_PROFILE.LOGIN_ID
      WHERE COMMON_USER.LOGIN_ID = IP_LOGIN_ID;
    OP_OPERATE_CODE:=1;
    
   EXCEPTION
   WHEN NO_DATA_FOUND THEN 
       OP_OPERATE_CODE:=0;
  WHEN OTHERS THEN 
    OP_OPERATE_CODE:=-1;
  END SEL_BY_LOGINUD;
  
  
 /*====================================更新用户信息====================================================*/ 
  PROCEDURE UPDATE_INFO(
    IP_LOGIN_ID         IN COMMON_USER.LOGIN_ID%type ,
    IP_IDNUMBER         IN COMMON_USER.IDNUMBER%type DEFAULT NULL ,
    IP_USER_TYPE        IN COMMON_USER.USER_TYPE%type DEFAULT NULL ,
    IP_TRUE_NAME        IN COMMON_USER_PROFILE.TRUENAME%TYPE,
    OP_OPERATE_CODE OUT NUMBER
  )
  AS
  BEGIN
    
    UPDATE common_user
    SET common_user.idnumber = IP_IDNUMBER,
        common_user.user_type = IP_USER_TYPE
    WHERE 
      common_user.login_id = IP_LOGIN_ID;
     
     UPDATE common_user_profile
     SET  common_user_profile.truename = IP_TRUE_NAME
     WHERE
      login_id = IP_LOGIN_ID;
     
     COMMIT;
     OP_OPERATE_CODE:=1;
    
    EXCEPTION
    WHEN OTHERS THEN
      OP_OPERATE_CODE:=-1;
      ROLLBACK;
  END UPDATE_INFO;
  PROCEDURE updatePassword (
    IP_LOGIN_ID IN COMMON_USER.LOGIN_ID%type ,
    OP_PASSWROD IN COMMON_USER.ENCRYPTPASSWORD%TYPE,
	OP_NEW_PASSWORD IN COMMON_USER.ENCRYPTPASSWORD%TYPE,
    OP_CODE OUT NUMBER
 )AS
	T_USER_COUNT NUMBER(1,0) default 0;
	T_USER_PASSWORD COMMON_USER.ENCRYPTPASSWORD%TYPE;
	USER_NOT_EXIST_EXCEPTION exception;
	PASSWORD_NOT_MATCH EXCEPTION;
 BEGIN
	--检测用户权限
	SELECT COUNT(*) INTO T_USER_COUNT FROM COMMON_USER WHERE LOGIN_ID = IP_LOGIN_ID;
  OP_CODE:=0;
	IF T_USER_COUNT = 0 THEN
		RAISE USER_NOT_EXIST_EXCEPTION;
	END IF;
	
  select ENCRYPTPASSWORD into T_USER_PASSWORD from COMMON_USER WHERE LOGIN_ID = IP_LOGIN_ID;
  
	IF T_USER_PASSWORD <> OP_PASSWROD THEN
		RAISE PASSWORD_NOT_MATCH;
	END IF;
	
	UPDATE COMMON_USER SET ENCRYPTPASSWORD = OP_NEW_PASSWORD   WHERE LOGIN_ID = IP_LOGIN_ID;
	OP_CODE:=1;
	COMMIT;
	
	
EXCEPTION 
	WHEN USER_NOT_EXIST_EXCEPTION THEN
		BEGIN
			OP_CODE:=-6;
			ROLLBACK;
		END;
	WHEN 	PASSWORD_NOT_MATCH THEN 
		BEGIN
			OP_CODE:=-5;
			rollback;
		END;	
	when others then
		begin
			OP_CODE:=-1;
			rollback;
		end;
		
	
	
 END;
  
  
  
  
  PROCEDURE UPLOADUSERHEAD(
	IP_USER_ID IN COMMON_USER.LOGIN_ID%TYPE,
	IP_USERHEAD IN COMMON_USER_PROFILE.USERHEAD%TYPE,
	OP_CODE OUT NUMBER
)AS

BEGIN

	OP_CODE:=0;
	
	UPDATE COMMON_USER_PROFILE SET USERHEAD = IP_USERHEAD WHERE LOGIN_ID=IP_USER_ID;
	OP_CODE:=1;
	COMMIT;
	
	EXCEPTION 
		WHEN OTHERS THEN
		BEGIN
			OP_CODE:=-1;
			ROLLBACK;
		END;
	
	

END;







PROCEDURE UPDATEUSERPROFILE(
	IP_LOGIN_ID IN COMMON_USER.LOGIN_ID%TYPE,
	IP_BIRTHYEAR IN COMMON_USER_PROFILE.BIRTHYEAR%TYPE,
	IP_BIRTHMONTH IN COMMON_USER_PROFILE.BIRTHMONTH%TYPE,
	IP_BIRTHDAY IN COMMON_USER_PROFILE.BIRTHDAY%TYPE,
	IP_NICKNAME IN COMMON_USER.NICKNAME%TYPE,
	IP_SIGNATURE IN COMMON_USER_PROFILE.SIGNATURE%TYPE,
	IP_GENDER IN COMMON_USER_PROFILE.GENDER%TYPE,
	IP_ADDRESS IN COMMON_USER_PROFILE.ADDRESS%TYPE,
	IP_MAJORNAME IN COMMON_USER_PROFILE.MAJORID%TYPE,
	IP_CONSTELLATION IN COMMON_USER_PROFILE.CONSTELLATION%TYPE,
	IP_AGE IN COMMON_USER_PROFILE.AGE%TYPE,
	OP_CODE OUT NUMBER 
)AS
BEGIN
	OP_CODE :=0;
	--更新COMMON_USER
	UPDATE COMMON_USER SET COMMON_USER.NICKNAME = IP_NICKNAME WHERE LOGIN_ID=IP_LOGIN_ID;
	
	UPDATE COMMON_USER_PROFILE SET
		BIRTHYEAR = IP_BIRTHYEAR,
		BIRTHMONTH = IP_BIRTHMONTH,
		BIRTHDAY = IP_BIRTHDAY,
		SIGNATURE = IP_SIGNATURE,
		GENDER = IP_GENDER,
		ADDRESS = IP_ADDRESS,
		MAJORID = IP_MAJORNAME,
		CONSTELLATION = IP_CONSTELLATION,
		AGE = IP_AGE
	WHERE LOGIN_ID=IP_LOGIN_ID;
	OP_CODE :=1;
	COMMIT;
	
	EXCEPTION 
		WHEN OTHERS THEN
			BEGIN
					OP_CODE :=-1;
					ROLLBACK;
			END;
			
			
END;





END CA_PKG_COMMON_USER;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_DETAIL_FOOD
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_DETAIL_FOOD" 
IS
  -- insert
PROCEDURE ins(
    p_PUB_DATE       IN CA_DETAIL_FOOD.PUB_DATE%type DEFAULT NULL ,
    p_RECORD_ID      IN CA_DETAIL_FOOD.RECORD_ID%type ,
    p_FOOD_INTRODUCE IN CA_DETAIL_FOOD.FOOD_INTRODUCE%type DEFAULT NULL ,
    p_DELIVERY_PHONE IN CA_DETAIL_FOOD.DELIVERY_PHONE%type DEFAULT NULL ,
    --p_MERCHANT_ID    IN CA_DETAIL_FOOD.MERCHANT_ID%type DEFAULT NULL ,
    p_SALE_PRICE     IN CA_DETAIL_FOOD.SALE_PRICE%type DEFAULT NULL,
    op_ins_code out number
    )
IS
BEGIN
  INSERT
  INTO CA_DETAIL_FOOD
    (
      PUB_DATE ,
      RECORD_ID,
      FOOD_INTRODUCE ,
      DELIVERY_PHONE ,
     -- MERCHANT_ID ,
      SALE_PRICE
    )
    VALUES
    (
      p_PUB_DATE ,
      p_RECORD_ID ,
      p_FOOD_INTRODUCE ,
      p_DELIVERY_PHONE ,
     -- p_MERCHANT_ID ,
      p_SALE_PRICE
    );
    commit;
    op_ins_code:=1;
    
   exception
   when others then
    op_ins_code:=-1;
    
END;
-- update
PROCEDURE upd
  (
    p_PUB_DATE       IN CA_DETAIL_FOOD.PUB_DATE%type DEFAULT NULL ,
    p_RECORD_ID      IN CA_DETAIL_FOOD.RECORD_ID%type ,
    p_FOOD_INTRODUCE IN CA_DETAIL_FOOD.FOOD_INTRODUCE%type DEFAULT NULL ,
    p_DELIVERY_PHONE IN CA_DETAIL_FOOD.DELIVERY_PHONE%type DEFAULT NULL ,
    --p_MERCHANT_ID    IN CA_DETAIL_FOOD.MERCHANT_ID%type DEFAULT NULL ,
    p_SALE_PRICE     IN CA_DETAIL_FOOD.SALE_PRICE%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_DETAIL_FOOD
  SET PUB_DATE     = p_PUB_DATE ,
    FOOD_INTRODUCE = p_FOOD_INTRODUCE ,
    DELIVERY_PHONE = p_DELIVERY_PHONE ,
  --  MERCHANT_ID    = p_MERCHANT_ID ,
    SALE_PRICE     = p_SALE_PRICE
  WHERE RECORD_ID  = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_DETAIL_FOOD.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_DETAIL_FOOD WHERE RECORD_ID = p_RECORD_ID;
END;
END CA_PKG_DETAIL_FOOD;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_FEEDBACK
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_FEEDBACK" 
IS
  -- insert
PROCEDURE ins(
    p_MOBILE_TYPE             IN COMMON_FEEDBACK.MOBILE_TYPE%type DEFAULT NULL ,
    p_MOBILE_SOFTWARE_VERSION IN COMMON_FEEDBACK.MOBILE_SOFTWARE_VERSION%type DEFAULT NULL ,
    p_USER_ID                 IN COMMON_FEEDBACK.USER_ID%type DEFAULT NULL ,
  --  p_RECORD_ID               IN COMMON_FEEDBACK.RECORD_ID%type ,
    p_FB_CONTENT              IN COMMON_FEEDBACK.FB_CONTENT%type DEFAULT NULL ,
    p_MOBILE_OS_MODEL         IN COMMON_FEEDBACK.MOBILE_OS_MODEL%type DEFAULT NULL ,
    p_FB_DATE                 IN COMMON_FEEDBACK.FB_DATE%type DEFAULT NULL ,
    p_MOBILE_OS_VERSION       IN COMMON_FEEDBACK.MOBILE_OS_VERSION%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO COMMON_FEEDBACK
    (
      MOBILE_TYPE ,
      MOBILE_SOFTWARE_VERSION ,
      USER_ID ,
   --   RECORD_ID ,
      FB_CONTENT ,
      MOBILE_OS_MODEL ,
      FB_DATE ,
      MOBILE_OS_VERSION
    )
    VALUES
    (
      p_MOBILE_TYPE ,
      p_MOBILE_SOFTWARE_VERSION,
      p_USER_ID ,
    --  p_RECORD_ID ,
      p_FB_CONTENT ,
      p_MOBILE_OS_MODEL ,
      p_FB_DATE ,
      p_MOBILE_OS_VERSION
    );
END;
-- update
PROCEDURE upd
  (
    p_MOBILE_TYPE             IN COMMON_FEEDBACK.MOBILE_TYPE%type DEFAULT NULL ,
    p_MOBILE_SOFTWARE_VERSION IN COMMON_FEEDBACK.MOBILE_SOFTWARE_VERSION%type DEFAULT NULL ,
    p_USER_ID                 IN COMMON_FEEDBACK.USER_ID%type DEFAULT NULL ,
    p_RECORD_ID               IN COMMON_FEEDBACK.RECORD_ID%type ,
    p_FB_CONTENT              IN COMMON_FEEDBACK.FB_CONTENT%type DEFAULT NULL ,
    p_MOBILE_OS_MODEL         IN COMMON_FEEDBACK.MOBILE_OS_MODEL%type DEFAULT NULL ,
    p_FB_DATE                 IN COMMON_FEEDBACK.FB_DATE%type DEFAULT NULL ,
    p_MOBILE_OS_VERSION       IN COMMON_FEEDBACK.MOBILE_OS_VERSION%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE COMMON_FEEDBACK
  SET MOBILE_TYPE           = p_MOBILE_TYPE ,
    MOBILE_SOFTWARE_VERSION = p_MOBILE_SOFTWARE_VERSION ,
    USER_ID                 = p_USER_ID ,
    FB_CONTENT              = p_FB_CONTENT ,
    MOBILE_OS_MODEL         = p_MOBILE_OS_MODEL ,
    FB_DATE                 = p_FB_DATE ,
    MOBILE_OS_VERSION       = p_MOBILE_OS_VERSION
  WHERE RECORD_ID           = p_RECORD_ID;
END;

-- del.删除
PROCEDURE del(
    IP_RECORD_ID IN COMMON_FEEDBACK.RECORD_ID%type,
    OP_DEL_CODE OUT NUMBER   
    )
IS
BEGIN
  DELETE FROM COMMON_FEEDBACK WHERE RECORD_ID = IP_RECORD_ID;
  COMMIT;
  OP_DEL_CODE:=1;
  
EXCEPTION 
WHEN OTHERS THEN
  OP_DEL_CODE:=-1;
  ROLLBACK;
  
END del;


 /*======================================查询=============================================*/   
  PROCEDURE  SEL(
    IP_RECORD_ID IN COMMON_FEEDBACK.RECORD_ID%type,
    OP_OPERATE_CODE OUT NUMBER,
    OP_SEL_RESULT OUT SYS_REFCURSOR
  )
  AS
  BEGIN
    OPEN OP_SEL_RESULT FOR 
    SELECT * FROM common_feedback WHERE common_feedback.record_id =  IP_RECORD_ID;
    OP_OPERATE_CODE:=1;
    
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
       OP_OPERATE_CODE:=0;
    WHEN OTHERS THEN
       OP_OPERATE_CODE:=-1;
  
  END SEL;
  
END CA_PKG_FEEDBACK;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_FOOD_COMMENT
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_FOOD_COMMENT" 
IS
  -- insert
PROCEDURE ins(
    p_MARK_VALUE      IN CA_FOOD_COMMENT.MARK_VALUE%type DEFAULT NULL ,
    p_COMMENT_DATE    IN CA_FOOD_COMMENT.COMMENT_DATE%type DEFAULT NULL ,
    p_USER_ID         IN CA_FOOD_COMMENT.USER_ID%type DEFAULT NULL ,
    --p_RECORD_ID       IN CA_FOOD_COMMENT.RECORD_ID%type ,
    p_COMMENT_CONTENT IN CA_FOOD_COMMENT.COMMENT_CONTENT%type DEFAULT NULL ,
    p_COMMENT_TYPE    IN CA_FOOD_COMMENT.COMMENT_TYPE%type DEFAULT NULL ,
    p_REF_ID          IN CA_FOOD_COMMENT.REF_ID%type DEFAULT NULL ,
    p_PARENT_ID       IN CA_FOOD_COMMENT.PARENT_ID%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_FOOD_COMMENT
    (
      MARK_VALUE ,
      COMMENT_DATE ,
      USER_ID ,
     -- RECORD_ID ,
      COMMENT_CONTENT ,
      COMMENT_TYPE ,
      REF_ID ,
      PARENT_ID
    )
    VALUES
    (
      p_MARK_VALUE ,
      p_COMMENT_DATE ,
      p_USER_ID ,
    --  p_RECORD_ID ,
      p_COMMENT_CONTENT ,
      p_COMMENT_TYPE ,
      p_REF_ID ,
      p_PARENT_ID
    );
END;
-- update
PROCEDURE upd
  (
    p_MARK_VALUE      IN CA_FOOD_COMMENT.MARK_VALUE%type DEFAULT NULL ,
    p_COMMENT_DATE    IN CA_FOOD_COMMENT.COMMENT_DATE%type DEFAULT NULL ,
    p_USER_ID         IN CA_FOOD_COMMENT.USER_ID%type DEFAULT NULL ,
    p_RECORD_ID       IN CA_FOOD_COMMENT.RECORD_ID%type ,
    p_COMMENT_CONTENT IN CA_FOOD_COMMENT.COMMENT_CONTENT%type DEFAULT NULL ,
    p_COMMENT_TYPE    IN CA_FOOD_COMMENT.COMMENT_TYPE%type DEFAULT NULL ,
    p_REF_ID          IN CA_FOOD_COMMENT.REF_ID%type DEFAULT NULL ,
    p_PARENT_ID       IN CA_FOOD_COMMENT.PARENT_ID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_FOOD_COMMENT
  SET MARK_VALUE    = p_MARK_VALUE ,
    COMMENT_DATE    = p_COMMENT_DATE ,
    USER_ID         = p_USER_ID ,
    COMMENT_CONTENT = p_COMMENT_CONTENT ,
    COMMENT_TYPE    = p_COMMENT_TYPE ,
    REF_ID          = p_REF_ID ,
    PARENT_ID       = p_PARENT_ID
  WHERE RECORD_ID   = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_FOOD_COMMENT.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_FOOD_COMMENT WHERE RECORD_ID = p_RECORD_ID;
END;
END CA_PKG_FOOD_COMMENT;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_LOCATION
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_LOCATION" 
IS


/*=======================================更新用户最新位置信息=====================================*/
  PROCEDURE UPD_LOACTION(
    IP_USER_ID IN NVARCHAR2,
    IP_LONGTITUDE IN NUMBER,
    IP_LATITUDE IN NUMBER,
    OP_SEL_CODE OUT NUMBER,
    OP_SEL_RESULT OUT SYS_REFCURSOR
  )
  AS
    T_USER_ADDRESS NVARCHAR2(200);
    T_ADDRESS NVARCHAR2(200);
    T_USER_COLLEGE_NO NVARCHAR2(2);
    T_USER_MAJOR_NO NVARCHAR2(2);
    T_COLLEGE_NO NVARCHAR2(2);
    T_MAJOR_NO NVARCHAR2(2);
    T_USER_GRADE_NO NVARCHAR2(4);
    T_GRADE_NO NVARCHAR2(4);
    T_MARJOR_NICKNAME NVARCHAR2(20);
    T_REC CA_T_NEAYBY%ROWTYPE;
    T_CURSOR SYS_REFCURSOR;
    T_USER_STUNUMBER_LEN NUMBER(2) ;
    T_USER_NO NVARCHAR2(20);
    T_DISTANCE NUMBER(4,0);
    T_MSG NVARCHAR2(200);
  BEGIN
    OP_SEL_CODE:=-1;
    --更新用户资料
    UPDATE COMMON_USER_PROFILE 
    SET
    LONGTITUDE = IP_LONGTITUDE,
    LASTITUDE = IP_LATITUDE,
    LASTUPDATE = TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi')
    WHERE LOGIN_ID =IP_USER_ID ; 
    COMMIT;
    
    --删除之前的临时数据
    DELETE  FROM CA_T_NEAYBY;
    COMMIT;
    
    --获取数据并插入
    INSERT INTO CA_T_NEAYBY
    (
      LOGIN_ID,
      UHEAD,
      SIGNATURE,
      LASTLOCATION,
      LONGTITUDE,
      LATITUDE,
      GENDER,
      ID_NUMBER,
      NICKNAME
    ) 
    SELECT 
      DISTINCT(COMMON_USER.LOGIN_ID),
      common_user_profile.USERHEAD,
      common_user_profile.SIGNATURE,
      common_user_profile.LASTUPDATE,
      common_user_profile.LONGTITUDE,
      common_user_profile.LASTITUDE,
      common_user_profile.GENDER,
      COMMON_USER.IDNUMBER,
      COMMON_USER.NICKNAME
    FROM 
    COMMON_USER LEFT JOIN common_user_profile 
    ON COMMON_USER.LOGIN_ID = common_user_profile.LOGIN_ID
    WHERE ALLOW_SEARCH =1 AND
    LONGTITUDE IS NOT NULL
    AND
    LASTITUDE IS NOT NULL
    AND 
    LASTUPDATE IS NOT NULL
    ORDER BY LASTITUDE DESC ;
    
    --查询用户住址
    SELECT common_user.IDNUMBER INTO T_USER_ADDRESS FROM common_user WHERE LOGIN_ID = IP_USER_ID;
    --查询用户学号和专业号
      IF LENGTH(IP_USER_ID) = 12 THEN
        BEGIN
          T_USER_COLLEGE_NO:=substr(IP_USER_ID,5,2);--学院号
          T_USER_MAJOR_NO:=substr(IP_USER_ID,7,2);--专业号
          T_USER_GRADE_NO:=substr(IP_USER_ID,0,4);--年级号
      
        END;
      elsif LENGTH(IP_USER_ID) = 4 THEN
        BEGIN
            T_USER_NO:=IP_USER_ID;
        END;
      END IF;
      --选择数据到游标
      OPEN T_CURSOR FOR 
        SELECT * FROM CA_T_NEAYBY;
       
       --打开游标
  
      LOOP
      --遍历游标
        
        FETCH T_CURSOR INTO T_REC;
          --没有数据则退出
          EXIT WHEN T_CURSOR%NOTFOUND;
          --数据处理
          --计算距离
          T_DISTANCE:=ca_pkg_common.getdistance(
          IP_LATITUDE,
          IP_LONGTITUDE,
          T_REC.LATITUDE,
          T_REC.LONGTITUDE
          )*1000;
          
          IF T_DISTANCE > 1000 THEN--如果距离大于1000m则删除
            BEGIN 
              DELETE FROM ca_t_neayby WHERE login_id = T_REC.LOGIN_ID;
              COMMIT;
            END;
          ELSE
            BEGIN
               --更新距离
                 BEGIN
                  UPDATE ca_t_neayby SET distance = T_DISTANCE WHERE login_id = T_REC.LOGIN_ID;
                  COMMIT;
                 END ;
               --计算是否是老乡
                IF CA_CHECK_NULL(T_USER_ADDRESS)<>1 THEN--不为1
                   BEGIN
                     SELECT T_REC.ID_NUMBER INTO T_ADDRESS FROM CA_T_NEAYBY WHERE LOGIN_ID = T_REC.LOGIN_ID;
                     IF  substr(T_USER_ADDRESS,0,6) = substr(T_ADDRESS,0,6) THEN
                      BEGIN
                        UPDATE CA_T_NEAYBY SET FELLOW = 1 WHERE  LOGIN_ID=T_REC.LOGIN_ID;
                        COMMIT;
                    END;
                     ELSIF   T_USER_ADDRESS <> T_ADDRESS THEN
                      BEGIN
                        UPDATE CA_T_NEAYBY SET FELLOW = 0 WHERE  LOGIN_ID=T_REC.LOGIN_ID;
                        COMMIT;
                      END;
                     END IF; 
                  END;
                  
                END IF;
                
                
                
               --计算是否同年级
                   IF LENGTH(T_REC.LOGIN_ID) = 12 THEN --普通学生,学号12位
                      BEGIN
                         T_GRADE_NO := substr(T_REC.LOGIN_ID,0,4);--年级号
                        
                        --判断
                          IF T_GRADE_NO=T_USER_GRADE_NO THEN
                              BEGIN
                                 UPDATE  CA_T_NEAYBY set ONEGRADE = 1 where LOGIN_ID = T_REC.LOGIN_ID;
                                 commit;
                              END;
                          ELSIF  T_GRADE_NO <> T_USER_GRADE_NO THEN
                             BEGIN
                                 UPDATE  CA_T_NEAYBY set onegrade = 0 where LOGIN_ID = T_REC.LOGIN_ID;
                                 commit;
                              END;
                          END IF;  
                       END;
                   ELSIF LENGTH(T_REC.LOGIN_ID)=4 THEN--教师
              
                      BEGIN
                        T_USER_NO:=IP_USER_ID;
                      END;
                
                  END IF;
                  
                  --计算是否是同专业
                 IF LENGTH(T_REC.LOGIN_ID)=12 THEN --普通学生,学号12位
                    BEGIN
                      T_COLLEGE_NO:=substr(T_REC.LOGIN_ID,5,2);--学院号
                      T_MAJOR_NO :=substr(T_REC.LOGIN_ID,7,2);--专业号
                      
                      IF T_COLLEGE_NO= T_USER_COLLEGE_NO AND  T_MAJOR_NO = T_USER_MAJOR_NO THEN
                            BEGIN
                                 
                                T_MARJOR_NICKNAME:=SEL_ONEMARJOR_NAME(T_GRADE_NO,T_COLLEGE_NO,T_MAJOR_NO);
                                UPDATE  CA_T_NEAYBY set  ONEMARJOR  = T_MARJOR_NICKNAME  where LOGIN_ID = T_REC.LOGIN_ID;
                                commit;
                                
                             END;
                      ELSE 
                             BEGIN
                                 UPDATE  CA_T_NEAYBY set  ONEMARJOR  = ''  where LOGIN_ID = T_REC.LOGIN_ID;
                                  commit;
                            END;
                      END IF;
                    END;
                 ELSIF LENGTH(T_REC.LOGIN_ID)=4 THEN
                   BEGIN
                        T_USER_NO:=IP_USER_ID;
                   END;
               END IF;
                  
            END;
          END IF;
          
        END LOOP;
      
      
     --关闭游标
     CLOSE T_CURSOR;
     
      
      OPEN OP_SEL_RESULT FOR
      SELECT distinct * FROM CA_T_NEAYBY order by lastlocation desc ;
    
     
    OP_SEL_CODE:=1;
    
  EXCEPTION 
    WHEN NO_DATA_FOUND THEN
      OP_SEL_CODE:=0;
      T_MSG:=SQLERRM;
    WHEN OTHERS THEN
      OP_SEL_CODE:=-1;
      T_MSG:=SQLERRM;
      ROLLBACK;
  END UPD_LOACTION;
 /*===============================查询统一专业的昵称(因为可能会抛出异常,所以单独进行处理)==============*/
  FUNCTION SEL_ONEMARJOR_NAME 
  (
    IP_GRADE_NO IN NVARCHAR2,
    IP_COLLEGE_NO  IN NVARCHAR2,
    IP_MARJOR_NO IN NVARCHAR2
  )
  RETURN NVARCHAR2
  AS
    T_MARJOR_NICKNMAE NVARCHAR2(10);
  BEGIN
       IF IP_GRADE_NO = '2010' AND IP_COLLEGE_NO = '13' AND  IP_MARJOR_NO ='01' THEN--10级数媒专业
          BEGIN
          T_MARJOR_NICKNMAE:='数媒';  
          RETURN T_MARJOR_NICKNMAE;
          END;
       ELSE  
             BEGIN
               SELECT  COMMON_MAJOR.NICK_NAME  INTO  T_MARJOR_NICKNMAE 
               FROM COMMON_MAJOR
               WHERE    MAJOR_NO =   IP_MARJOR_NO  
                AND COLLEGE_NO = IP_COLLEGE_NO;
            RETURN     T_MARJOR_NICKNMAE;
            END;
       END IF;
  EXCEPTION 
  WHEN NO_DATA_FOUND THEN
         T_MARJOR_NICKNMAE:='';  
        RETURN     T_MARJOR_NICKNMAE;
  WHEN OTHERS THEN
      T_MARJOR_NICKNMAE:='';
        RETURN     T_MARJOR_NICKNMAE;
      
  END SEL_ONEMARJOR_NAME;
/*=================================查询上同一节课的人。不采取分页============================================*/
  PROCEDURE SEL_ONE_LESSON(
    IP_USER_ID IN NVARCHAR2,
    IP_WEEK IN NUMBER,
    IP_DAY_OF_WEEK IN NUMBER,
    IP_NO_OF_DAY IN NUMBER,
    IP_LESSON_NO IN NVARCHAR2,
    OP_SEL_CODE OUT NUMBER,
    OP_SEL_RESULT OUT SYS_REFCURSOR
  )
  AS
    T_USER_ADDRESS NVARCHAR2(200);
    T_ADDRESS NVARCHAR2(200);
    T_USER_COLLEGE_NO NVARCHAR2(2);
    T_USER_MAJOR_NO NVARCHAR2(2);
    T_COLLEGE_NO NVARCHAR2(2);
    T_MAJOR_NO NVARCHAR2(2);
    T_USER_GRADE_NO NVARCHAR2(4);
    T_GRADE_NO NVARCHAR2(4);
    T_MARJOR_NICKNAME NVARCHAR2(20);
    T_REC CA_T_ONECLASS%ROWTYPE;
    T_CURSOR SYS_REFCURSOR;
    T_USER_STUNUMBER_LEN NUMBER(2) ;
    T_USER_NO NVARCHAR2(20);
  BEGIN
    OP_SEL_CODE :=-1;
    --OPEN OP_SEL_RESULT FOR
    
    --delete all datas
    delete from ca_t_oneclass;
    commit;
    
    INSERT INTO ca_t_oneclass(STUNO,CLASSNAME,LESSON_ADD,NICKNAME,USERHEAD,SIGNATURE,GENDER)
      SELECT  
      distinct(V_MOBILE_LESSON.STUNO), 
      V_MOBILE_LESSON.CLASSNAME,
      V_MOBILE_LESSON.LESSON_ADD,
      common_user.NICKNAME,
      COMMON_USER_PROFILE.USERHEAD,
      COMMON_USER_PROFILE.SIGNATURE,
      COMMON_USER_PROFILE.GENDER
      FROM 
      V_MOBILE_LESSON LEFT JOIN common_user
      ON V_MOBILE_LESSON.STUNO = common_user.LOGIN_ID
      LEFT JOIN  COMMON_USER_PROFILE 
      ON common_user.LOGIN_ID = COMMON_USER_PROFILE.LOGIN_ID
      WHERE CLASSNO = IP_LESSON_NO AND common_user.REGSTATUS = 0
        AND WEEKOFSEMESTER = IP_WEEK
        AND DAYOFWEEK = IP_DAY_OF_WEEK
        AND NOOFDAY = IP_NO_OF_DAY
      ;
    
--查询用户住址
    SELECT common_user.IDNUMBER INTO T_USER_ADDRESS FROM common_user WHERE LOGIN_ID = IP_USER_ID;
    --查询用户学号和专业号
      IF LENGTH(IP_USER_ID) = 12 THEN
        BEGIN
          T_USER_COLLEGE_NO:=substr(IP_USER_ID,5,2);--学院号
          T_USER_MAJOR_NO:=substr(IP_USER_ID,7,2);--专业号
          T_USER_GRADE_NO:=substr(IP_USER_ID,0,4);--年级号
        --  T_USER_NO:=IP_USER_ID;
        END;
      elsif LENGTH(IP_USER_ID) = 4 THEN
        BEGIN
            T_USER_NO:=IP_USER_ID;
        END;
      END IF;
         
   
   
   --选择数据到游标
      OPEN T_CURSOR FOR 
        SELECT * FROM ca_t_oneclass;
       
       --打开游标
  
      LOOP
      --遍历游标
        
        FETCH T_CURSOR INTO T_REC;
          --没有数据则退出
          EXIT WHEN T_CURSOR%NOTFOUND;
          --数据处理
          --计算是否是老乡
          IF CA_CHECK_NULL(T_USER_ADDRESS)<>1 THEN--不为1
            BEGIN
               SELECT common_user.IDNUMBER INTO T_ADDRESS FROM common_user WHERE LOGIN_ID = T_REC.STUNO;
               IF  substr(T_USER_ADDRESS,0,6) = substr(T_ADDRESS,0,6) THEN
                BEGIN
                  UPDATE CA_T_ONECLASS SET FELLOW = 1 WHERE  STUNO=T_REC.STUNO;
                  COMMIT;
              END;
               ELSIF   T_USER_ADDRESS <> T_ADDRESS THEN
                BEGIN
                  UPDATE CA_T_ONECLASS SET FELLOW = 0 WHERE  STUNO=T_REC.STUNO;
                  COMMIT;
                END;
               END IF; 
            END;
            
          END IF;
          
          
          
         --计算是否同年级
             IF LENGTH(T_REC.STUNO) = 12 THEN --普通学生,学号12位
                BEGIN
                   T_GRADE_NO := substr(T_REC.STUNO,0,4);--年级号
                  
                  --判断
                    IF T_GRADE_NO=T_USER_GRADE_NO THEN
                        BEGIN
                           UPDATE  ca_t_oneclass set onegrade = 1 where stuno = T_REC.STUNO;
                           commit;
                        END;
                    ELSIF  T_GRADE_NO <> T_USER_GRADE_NO THEN
                       BEGIN
                           UPDATE  ca_t_oneclass set onegrade = 0 where stuno = T_REC.STUNO;
                           commit;
                        END;
                    END IF;  
                 END;
             ELSIF LENGTH(T_REC.STUNO)=4 THEN--教师
        
                BEGIN
                  T_USER_NO:=IP_USER_ID;
                END;
          
            END IF;
            
            --计算是否是同专业
           IF LENGTH(T_REC.STUNO)=12 THEN --普通学生,学号12位
              BEGIN
                T_COLLEGE_NO:=substr(T_REC.STUNO,5,2);--学院号
                T_MAJOR_NO :=substr(T_REC.STUNO,7,2);--专业号
                
                IF T_COLLEGE_NO= T_USER_COLLEGE_NO AND  T_MAJOR_NO = T_USER_MAJOR_NO THEN
                      BEGIN
                           
                          T_MARJOR_NICKNAME:=SEL_ONEMARJOR_NAME(T_GRADE_NO,T_COLLEGE_NO,T_MAJOR_NO);
                          UPDATE  ca_t_oneclass set  onemarjor  = T_MARJOR_NICKNAME  where stuno = T_REC.STUNO;
                          commit;
                          
                       END;
                ELSE 
                       BEGIN
                           UPDATE  ca_t_oneclass set  onemarjor  = ''  where stuno = T_REC.STUNO;
                            commit;
                      END;
                END IF;
              END;
           ELSIF LENGTH(T_REC.STUNO)=4 THEN
             BEGIN
                  T_USER_NO:=IP_USER_ID;
             END;
         END IF;
         
          
          
          
      END LOOP;
      
      
     --关闭游标
     CLOSE T_CURSOR;
     
     
     --将查询数据选择到由表中
     OPEN OP_SEL_RESULT FOR
      SELECT distinct * FROM ca_t_oneclass ;
     OP_SEL_CODE:=1;
   EXCEPTION 
    WHEN NO_DATA_FOUND THEN
      OP_SEL_CODE:=0;
    WHEN OTHERS THEN
      OP_SEL_CODE:=-1;
   
  END SEL_ONE_LESSON;
  
  
  
  
END CA_PKG_LOCATION;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_MERCHANT
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_MERCHANT" 
IS

  -- insert
  /**
  *返回代码：
  *1表示创建成功
  *-1表示创建用户出现异常
  *-2表示用户已经存在
  */
PROCEDURE ins(
       p_LOGIN_ID         IN CA_MERCHANT.LOGIN_ID%type DEFAULT NULL ,
      p_REG_IP           IN CA_MERCHANT.REG_IP%type DEFAULT NULL ,
      p_CONTACT_NAME     IN CA_MERCHANT.CONTACT_NAME%type DEFAULT NULL ,
      p_CONTACT_PHONE    IN CA_MERCHANT.CONTACT_PHONE%type DEFAULT NULL ,
      p_MERCHANT_NAME    IN CA_MERCHANT.MERCHANT_NAME%type DEFAULT NULL ,
      p_ENCRYPTPASSWORD  IN CA_MERCHANT.ENCRYPTPASSWORD%type DEFAULT NULL ,
      p_MERCHANT_ADDRESS IN CA_MERCHANT.MERCHANT_ADDRESS%type DEFAULT NULL,
      
      OP_INS_CODE OUT NUMBER
      ---后台登录
     -- U_HEAD IN VARCHAR2,--用户头像
     -- U_GROUP_ID IN NUMBER,
      --记录日志
     -- IP_CUR_LOGIN_ID IN NVARCHAR2,--当前登录用户IP
     -- IP_CUR_LOGIN_IP IN VARCHAR2, --当前登录用户IP
     -- OP_INS_CODE OUT NUMBER
      )
IS
  t_user_count number(1);
  user_exit_exception exception;
BEGIN
  --查询用户是否存在
    select count(*) into t_user_count from CA_MERCHANT where login_id = 'p_LOGIN_ID';
    
    if t_user_count <> 0 then
      raise user_exit_exception;
    end if;
    
  INSERT
  INTO CA_MERCHANT
    (
      
      LAST_MODIFY ,
      LOGIN_ID ,
      REG_IP ,
      REG_DATE ,
      CONTACT_NAME ,
      CONTACT_PHONE ,
      MERCHANT_NAME ,
      ENCRYPTPASSWORD ,
      MERCHANT_ADDRESS
    )
    VALUES
    (
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi:ss'),
      p_LOGIN_ID ,
      p_REG_IP ,
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi:ss'),
      p_CONTACT_NAME ,
      p_CONTACT_PHONE ,
      p_MERCHANT_NAME ,
      p_ENCRYPTPASSWORD ,
      p_MERCHANT_ADDRESS
    );
    
   
    COMMIT;
    OP_INS_CODE:=1;
    
  EXCEPTION
  when user_exit_exception then
    begin
      rollback;
       OP_INS_CODE:=-2;
    end;
  WHEN OTHERS THEN
    begin
    rollback;
    OP_INS_CODE:=-1;
    end;
    
END;
-- update
PROCEDURE upd
  (
    p_ODER_LIST        IN CA_MERCHANT.ODER_LIST%type DEFAULT NULL ,
    p_LAST_MODIFY      IN CA_MERCHANT.LAST_MODIFY%type DEFAULT NULL ,
    p_LOGIN_ID         IN CA_MERCHANT.LOGIN_ID%type DEFAULT NULL ,
    p_REG_IP           IN CA_MERCHANT.REG_IP%type DEFAULT NULL ,
    p_REG_DATE         IN CA_MERCHANT.REG_DATE%type DEFAULT NULL ,
    p_CONTACT_NAME     IN CA_MERCHANT.CONTACT_NAME%type DEFAULT NULL ,
    p_RECORD_ID        IN CA_MERCHANT.RECORD_ID%type ,
    p_CONTACT_PHONE    IN CA_MERCHANT.CONTACT_PHONE%type DEFAULT NULL ,
    p_MERCHANT_NAME    IN CA_MERCHANT.MERCHANT_NAME%type DEFAULT NULL ,
    p_NEW_ORDER        IN CA_MERCHANT.NEW_ORDER%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN CA_MERCHANT.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_MERCHANT_ADDRESS IN CA_MERCHANT.MERCHANT_ADDRESS%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_MERCHANT
  SET ODER_LIST      = p_ODER_LIST ,
    LAST_MODIFY      = p_LAST_MODIFY ,
    LOGIN_ID         = p_LOGIN_ID ,
    REG_IP           = p_REG_IP ,
    REG_DATE         = p_REG_DATE ,
    CONTACT_NAME     = p_CONTACT_NAME ,
    CONTACT_PHONE    = p_CONTACT_PHONE ,
    MERCHANT_NAME    = p_MERCHANT_NAME ,
    NEW_ORDER        = p_NEW_ORDER ,
    ENCRYPTPASSWORD  = p_ENCRYPTPASSWORD ,
    MERCHANT_ADDRESS = p_MERCHANT_ADDRESS
  WHERE RECORD_ID    = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_MERCHANT.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_MERCHANT WHERE RECORD_ID = p_RECORD_ID;
END;

 PROCEDURE CHECK_USER_EXIST(
    IP_LOGIN_ID IN NVARCHAR2,
    OP_CHK_CODE OUT NUMBER
  )
  IS
   T_USER_COUNT NUMBER(1);
  BEGIN
    
    SELECT COUNT(*) INTO T_USER_COUNT FROM CA_MERCHANT WHERE LOGIN_ID =IP_LOGIN_ID ; 
    IF T_USER_COUNT = 0 THEN
      OP_CHK_CODE :=1;
    ELSE  
      OP_CHK_CODE:=0;
    END IF;
      
  END;
  
  
  

  
  
END CA_PKG_MERCHANT;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_RUNTIME_ANAL
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_RUNTIME_ANAL" 
IS
  -- insert
PROCEDURE ins(
    p_OBJECT_NAME IN CA_RUNTIME_ANAL.OBJECT_NAME%type DEFAULT NULL ,
  --  p_RECORD_ID   IN CA_RUNTIME_ANAL.RECORD_ID%type ,
    p_COUNT_TIME  IN CA_RUNTIME_ANAL.COUNT_TIME%type ,
    p_OBJECT_TYPE IN CA_RUNTIME_ANAL.OBJECT_TYPE%type ,
    p_AVER_TIME   IN CA_RUNTIME_ANAL.AVER_TIME%type DEFAULT NULL ,
    p_RECORD_DATE IN CA_RUNTIME_ANAL.RECORD_DATE%type DEFAULT NULL ,
    p_EXE_TIMES   IN CA_RUNTIME_ANAL.EXE_TIMES%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_RUNTIME_ANAL
    (
      OBJECT_NAME ,
    --  RECORD_ID ,
      COUNT_TIME ,
      OBJECT_TYPE ,
      AVER_TIME ,
      RECORD_DATE ,
      EXE_TIMES
    )
    VALUES
    (
      p_OBJECT_NAME ,
    --  p_RECORD_ID ,
      p_COUNT_TIME ,
      p_OBJECT_TYPE ,
      p_AVER_TIME ,
      p_RECORD_DATE ,
      p_EXE_TIMES
    );
END;
-- update
PROCEDURE upd
  (
    p_OBJECT_NAME IN CA_RUNTIME_ANAL.OBJECT_NAME%type DEFAULT NULL ,
    p_RECORD_ID   IN CA_RUNTIME_ANAL.RECORD_ID%type ,
    p_COUNT_TIME  IN CA_RUNTIME_ANAL.COUNT_TIME%type ,
    p_OBJECT_TYPE IN CA_RUNTIME_ANAL.OBJECT_TYPE%type ,
    p_AVER_TIME   IN CA_RUNTIME_ANAL.AVER_TIME%type DEFAULT NULL ,
    p_RECORD_DATE IN CA_RUNTIME_ANAL.RECORD_DATE%type DEFAULT NULL ,
    p_EXE_TIMES   IN CA_RUNTIME_ANAL.EXE_TIMES%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_RUNTIME_ANAL
  SET OBJECT_NAME = p_OBJECT_NAME ,
    COUNT_TIME    = p_COUNT_TIME ,
    OBJECT_TYPE   = p_OBJECT_TYPE ,
    AVER_TIME     = p_AVER_TIME ,
    RECORD_DATE   = p_RECORD_DATE ,
    EXE_TIMES     = p_EXE_TIMES
  WHERE RECORD_ID = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_RUNTIME_ANAL.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_RUNTIME_ANAL WHERE RECORD_ID = p_RECORD_ID;
END;
END CA_PKG_RUNTIME_ANAL;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_SENSITIVE
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_SENSITIVE" 
IS
  -- insert
PROCEDURE ins(
    p_SOURCE        IN CA_SENSITIVE.SOURCE%type ,
 --   p_RECORD_ID     IN CA_SENSITIVE.RECORD_ID%type ,
    p_SENSITIVE_STR IN CA_SENSITIVE.SENSITIVE_STR%type DEFAULT NULL,
    OP_OPERATE_CODE OUT NUMBER
    )
IS
BEGIN

  INSERT
  INTO CA_SENSITIVE
    (
      "SOURCE" ,
      --RECORD_ID ,
      SENSITIVE_STR
    )
    VALUES
    (
      p_SOURCE ,
      --p_RECORD_ID ,
      p_SENSITIVE_STR
    );
    
    COMMIT;
    OP_OPERATE_CODE:=1;
    
    EXCEPTION
    WHEN OTHERS THEN
      OP_OPERATE_CODE:=-1;
      
END;
-- update
PROCEDURE upd
  (
    p_SOURCE        IN CA_SENSITIVE.SOURCE%type ,
    p_RECORD_ID     IN CA_SENSITIVE.RECORD_ID%type ,
    p_SENSITIVE_STR IN CA_SENSITIVE.SENSITIVE_STR%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_SENSITIVE
  SET SOURCE      = p_SOURCE ,
    SENSITIVE_STR = p_SENSITIVE_STR
  WHERE RECORD_ID = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_SENSITIVE.RECORD_ID%type,
     OP_OPERATE_CODE OUT NUMBER)
IS
BEGIN
    DELETE FROM CA_SENSITIVE WHERE RECORD_ID = p_RECORD_ID;
    COMMIT;
    OP_OPERATE_CODE:=1;
  
  EXCEPTION
  WHEN OTHERS THEN
  OP_OPERATE_CODE:=-1;
  ROLLBACK;
END;
/*==========================分页查询=================================*/
PROCEDURE PAGE_SENSITIVE(
    IP_PAGE_INDEX IN NUMBER,--索引
    IP_PAGE_SIZE  IN NUMBER,
    OP_SELECT_RESULT OUT SYS_REFCURSOR,
    OP_SELECT_CODE OUT NUMBER,
    OP_SUMALL OUT NUMBER )
AS
  V_CUR_PAGE NUMBER;
BEGIN
  V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
  OPEN OP_SELECT_RESULT FOR
  SELECT DISTINCT *
  FROM
    (SELECT T.*,
      ROWNUM RN
    FROM
      (
        SELECT * FROM ca_sensitive 
      ) T
    )
  WHERE RN >= (V_CUR_PAGE + 1)
  AND RN   <= (V_CUR_PAGE + IP_PAGE_SIZE);
  
  SELECT  COUNT(*)  INTO OP_SUMALL FROM CA_SENSITIVE;
    OP_SELECT_CODE:=1;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    OP_SELECT_CODE:=0;
  WHEN OTHERS THEN
     OP_SELECT_CODE:=-1;
    
END PAGE_SENSITIVE;

END CA_PKG_SENSITIVE;

/
--------------------------------------------------------
--  DDL for Package Body CA_PKG_SIMPLE_FOOD
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_PKG_SIMPLE_FOOD" 
IS
  -- insert
PROCEDURE ins(
   --简单信息
      p_FOOD_CATEGORY_ID IN CA_SIMPLE_FOOD.FOOD_CATEGORY_ID%type DEFAULT NULL ,
      p_WORSE_MARK       IN CA_SIMPLE_FOOD.WORSE_MARK%type DEFAULT NULL ,
      p_MARK_VALUE       IN CA_SIMPLE_FOOD.MARK_VALUE%type DEFAULT NULL ,
      --p_RECORD_ID        IN CA_SIMPLE_FOOD.RECORD_ID%type ,
      p_FOOD_TYPE_ID     IN CA_SIMPLE_FOOD.FOOD_TYPE_ID%type DEFAULT NULL ,
      p_FOOD_IMG         IN CA_SIMPLE_FOOD.FOOD_IMG%type DEFAULT NULL ,
      p_FOOD_PRICE       IN CA_SIMPLE_FOOD.FOOD_PRICE%type DEFAULT NULL ,
      p_GOOD_MARK        IN CA_SIMPLE_FOOD.GOOD_MARK%type DEFAULT NULL ,
      p_FOOD_NAME        IN CA_SIMPLE_FOOD.FOOD_NAME%type DEFAULT NULL,
      --详情
      --p_PUB_DATE       IN CA_DETAIL_FOOD.PUB_DATE%type DEFAULT NULL ,
   --   p_RECORD_ID      IN CA_DETAIL_FOOD.RECORD_ID%type ,
      p_FOOD_INTRODUCE IN CA_DETAIL_FOOD.FOOD_INTRODUCE%type DEFAULT NULL ,
      p_DELIVERY_PHONE IN CA_DETAIL_FOOD.DELIVERY_PHONE%type DEFAULT NULL ,
      p_MERCHANT_ID    IN CA_SIMPLE_FOOD.MERCHANT_ID%type DEFAULT NULL,
      p_SALE_PRICE     IN CA_DETAIL_FOOD.SALE_PRICE%type DEFAULT NULL,
      OP_INS_CODE out number
    )
IS
  t_record_id CA_SIMPLE_FOOD.RECORD_ID%type;
  t_ins_detail_code   number(1);
BEGIN
  t_record_id:=CA_SEQ_SIMPLE_FOOD.nextval;
  t_ins_detail_code:=0;
  op_ins_code:=0;
  BEGIN
  --插入简单数据
  INSERT
  INTO CA_SIMPLE_FOOD
    
    (
      FOOD_CATEGORY_ID ,
      WORSE_MARK ,
      MARK_VALUE ,
      RECORD_ID ,
      FOOD_TYPE_ID ,
      FOOD_IMG ,
      FOOD_PRICE ,
      GOOD_MARK ,
      FOOD_NAME,
      MERCHANT_ID
    )
    VALUES
    (
      p_FOOD_CATEGORY_ID ,
      p_WORSE_MARK ,
      p_MARK_VALUE ,
      t_record_id ,
      p_FOOD_TYPE_ID ,
      p_FOOD_IMG ,
      p_FOOD_PRICE ,
      p_GOOD_MARK ,
      p_FOOD_NAME,
      p_MERCHANT_ID
    );
    
    --详细数据
      CA_PKG_DETAIL_FOOD.ins(
         TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi:ss'),
         t_record_id,
         p_FOOD_INTRODUCE,
         p_DELIVERY_PHONE,
      --   p_MERCHANT_ID,
         p_SALE_PRICE,
         t_ins_detail_code
    ); 
    
    if t_ins_detail_code =1 then
      begin
    op_ins_code:=1;
      commit;
      end;
    else 
      begin
    op_ins_code:=-1;
      rollback;
      end;
    end if;
    
   exception
   when others then
    op_ins_code:=-1;
    rollback;
   END; 
    
END;
-- update
PROCEDURE upd
  (
    p_FOOD_CATEGORY_ID IN CA_SIMPLE_FOOD.FOOD_CATEGORY_ID%type DEFAULT NULL ,
    p_WORSE_MARK       IN CA_SIMPLE_FOOD.WORSE_MARK%type DEFAULT NULL ,
    p_MARK_VALUE       IN CA_SIMPLE_FOOD.MARK_VALUE%type DEFAULT NULL ,
    p_RECORD_ID        IN CA_SIMPLE_FOOD.RECORD_ID%type ,
    p_FOOD_TYPE_ID     IN CA_SIMPLE_FOOD.FOOD_TYPE_ID%type DEFAULT NULL ,
    p_FOOD_IMG         IN CA_SIMPLE_FOOD.FOOD_IMG%type DEFAULT NULL ,
    p_FOOD_PRICE       IN CA_SIMPLE_FOOD.FOOD_PRICE%type DEFAULT NULL ,
    p_GOOD_MARK        IN CA_SIMPLE_FOOD.GOOD_MARK%type DEFAULT NULL ,
    p_FOOD_NAME        IN CA_SIMPLE_FOOD.FOOD_NAME%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_SIMPLE_FOOD
  SET FOOD_CATEGORY_ID = p_FOOD_CATEGORY_ID ,
    WORSE_MARK         = p_WORSE_MARK ,
    MARK_VALUE         = p_MARK_VALUE ,
    FOOD_TYPE_ID       = p_FOOD_TYPE_ID ,
    FOOD_IMG           = p_FOOD_IMG ,
    FOOD_PRICE         = p_FOOD_PRICE ,
    GOOD_MARK          = p_GOOD_MARK ,
    FOOD_NAME          = p_FOOD_NAME
  WHERE RECORD_ID      = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_SIMPLE_FOOD.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_SIMPLE_FOOD WHERE RECORD_ID = p_RECORD_ID;
END;

 /*=======================================获取指定的类别内容数据------------------------------------------------------*/
 PROCEDURE SEL_BY_TYPE(
  IP_TYPE_ID IN NUMBER,
  OP_SEL_CODE OUT NUMBER,
  OP_SEL_RESULT OUT SYS_REFCURSOR
 )
 IS 
 BEGIN
    OPEN OP_SEL_RESULT FOR
      
        Select 
        RECORD_ID,
        FOOD_NAME,
        FOOD_PRICE,
        GOOD_MARK,
        WORSE_MARK,
        MARK_VALUE,
        FOOD_TYPE_ID,
        FOOD_CATEGORY_ID,
        MERCHANT_ID
        from ca_simple_food 
        where food_type_id = IP_TYPE_ID
        GROUP BY  MERCHANT_ID ,RECORD_ID,FOOD_NAME,FOOD_PRICE,MARK_VALUE,FOOD_TYPE_ID,  GOOD_MARK,
        WORSE_MARK,FOOD_CATEGORY_ID
        ORDER BY MERCHANT_ID ASC,MARK_VALUE DESC
        ;
      
      
    
      OP_SEL_CODE:=1;
      
   EXCEPTION 
   WHEN NO_DATA_FOUND THEN
       OP_SEL_CODE:=0;
   WHEN OTHERS THEN
       OP_SEL_CODE:=-1;
 END;
 
 procedure sel_by_id
 (
  IP_RECORD_ID IN NUMBER,
  OP_SEL_CODE OUT NUMBER,
  OP_SEL_RESULT OUT SYS_REFCURSOR
 )
 IS
 BEGIN
   OPEN OP_SEL_RESULT FOR
    select * from ca_simple_food,ca_detail_food 
  where ca_simple_food.record_id = ca_detail_food.record_id
  and ca_simple_food.record_id = IP_RECORD_ID;
    
  OP_SEL_CODE:=1;
      
   EXCEPTION 
   WHEN NO_DATA_FOUND THEN
       OP_SEL_CODE:=0;
   WHEN OTHERS THEN
       OP_SEL_CODE:=-1;
 END ;
 
 /*=========================================获取推荐===========================================*/
PROCEDURE SEL_RECOMMAND
(
  
  IP_NEED_SIZE IN NUMBER,
  IP_KEYWORDS IN NVARCHAR2,
  OP_SEL_CODE OUT NUMBER,
  OP_SEL_RESULT OUT SYS_REFCURSOR
)
IS
BEGIN
 OPEN OP_SEL_RESULT FOR
  SELECT * FROM (
    SELECT * FROM(
     SELECT T.*,ROWNUM RN FROM 
      (SELECT * FROM ca_simple_food
      WHERE FOOD_NAME LIKE '%'||IP_KEYWORDS||'%'
      ORDER BY MARK_VALUE DESC)
     T
   )
 ) 
 WHERE RN <= IP_NEED_SIZE; 
  OP_SEL_CODE:=1;

  EXCEPTION 
   WHEN NO_DATA_FOUND THEN
       OP_SEL_CODE:=0;
   WHEN OTHERS THEN
       OP_SEL_CODE:=-1;
END ;
 PROCEDURE DO_MARK(
  IP_MARK_TYPE IN NUMBER,
  IP_RECORD_ID IN NUMBER,
  OP_LAST_MARK_VALUE OUT VARCHAR2,
  OP_OP_CODE OUT NUMBER
)
IS
   T_GOOD_MARK CA_SIMPLE_FOOD.GOOD_MARK%TYPE;
   T_WORSE_MARK CA_SIMPLE_FOOD.WORSE_MARK%TYPE;
   
BEGIN
      IF IP_MARK_TYPE = 1 THEN  
        BEGIN
          UPDATE CA_SIMPLE_FOOD 
          SET GOOD_MARK = GOOD_MARK+1
          WHERE RECORD_ID = IP_RECORD_ID;
          COMMIT;
        END;
      ELSIF IP_MARK_TYPE=2 THEN
        BEGIN
          UPDATE CA_SIMPLE_FOOD 
          SET WORSE_MARK = WORSE_MARK+1
          WHERE RECORD_ID = IP_RECORD_ID;
          COMMIT;
        END;
        
      END IF;
      
      SELECT GOOD_MARK,WORSE_MARK INTO T_GOOD_MARK,T_WORSE_MARK 
      FROM CA_SIMPLE_FOOD
      WHERE  RECORD_ID = IP_RECORD_ID;
      
      OP_OP_CODE:=1;
      OP_LAST_MARK_VALUE:=T_GOOD_MARK||','||T_WORSE_MARK;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
  ROLLBACK;
    OP_OP_CODE:=-1;
    OP_LAST_MARK_VALUE:='';
      
END;



PROCEDURE SEL_BY_TYPE_V2(
  IP_TYPE_ID IN NUMBER,
  OP_SEL_CODE OUT NUMBER,
  OP_SEL_RESULT OUT SYS_REFCURSOR,
  OP_ROWCOUNT OUT NUMBER,
  OP_MSG OUT NVARCHAR2
 )
 IS 
 BEGIN
    OPEN OP_SEL_RESULT FOR
      
        SELECT   *
        FROM V_FOOD_LIST 
        WHERE FOOD_TYPE_ID = IP_TYPE_ID
        ORDER BY MERCHANT_ID ASC,MARK_VALUE DESC
        ; 
      
			
		SELECT COUNT(*) INTO OP_ROWCOUNT
		FROM V_FOOD_LIST 
        WHERE FOOD_TYPE_ID = IP_TYPE_ID
		; 
	OP_SEL_CODE:=1;
    OP_MSG:='';
   EXCEPTION 
   WHEN NO_DATA_FOUND THEN
	begin
       OP_SEL_CODE:=0;
	   OP_MSG :='没有找到数据';	
	end;
   WHEN OTHERS THEN
     begin
       OP_SEL_CODE:=-2;
	   OP_MSG:='{msg:'||sqlerrm||'}';
	end;
 END;	
 
 
 PROCEDURE SEL_BY_ID_V2
 (
  IP_RECORD_ID IN NUMBER,
  IP_USER_ID IN  COMMON_USER.LOGIN_ID%TYPE,
  OP_SEL_CODE OUT NUMBER,
  
  OP_SEL_RESULT OUT SYS_REFCURSOR,
 -- OP_CODE OUT NUMBER,
  OP_MSG  OUT NVARCHAR2	
 )
 IS
 BEGIN
  
      OPEN OP_SEL_RESULT FOR
    SELECT CA_SIMPLE_FOOD.*,CA_DETAIL_FOOD.*, CA_MERCHANT.MERCHANT_NAME,COMMON_USER_FAV_tapi.ISFAV_V3(IP_USER_ID,IP_RECORD_ID,1) AS  ISFAV  FROM CA_SIMPLE_FOOD,CA_DETAIL_FOOD,CA_MERCHANT 
  WHERE CA_SIMPLE_FOOD.RECORD_ID = CA_DETAIL_FOOD.RECORD_ID AND CA_SIMPLE_FOOD.MERCHANT_ID=CA_MERCHANT.LOGIN_ID
  AND CA_SIMPLE_FOOD.RECORD_ID = IP_RECORD_ID
  
  ;
    
	OP_SEL_CODE:=1;
    OP_MSG:='';
	  
   EXCEPTION 
   WHEN NO_DATA_FOUND THEN
	BEGIN
       OP_SEL_CODE:=0;
	   OP_MSG:='没有找到数据';
	END;
   WHEN OTHERS THEN
    BEGIN   
	   OP_SEL_CODE:=-1;
	   OP_MSG:='msg'||sqlerrm||'';
	END;
 END ;
 
 
 PROCEDURE SEL_RECOMMAND_V2
(
  
  IP_NEED_SIZE IN NUMBER,
  IP_KEYWORDS IN NVARCHAR2,
  OP_SEL_CODE OUT NUMBER,
  OP_SEL_RESULT OUT SYS_REFCURSOR,
  OP_ROWCOUNT OUT NUMBER,
  OP_MSG OUT NVARCHAR2
)
IS
BEGIN
 OPEN OP_SEL_RESULT FOR
  SELECT * FROM (
    SELECT * FROM(
     SELECT T.*,ROWNUM RN FROM 
      (SELECT * FROM ca_simple_food
      WHERE FOOD_NAME LIKE '%'||IP_KEYWORDS||'%'
      ORDER BY MARK_VALUE DESC)
     T
   )
 ) 
 WHERE RN <= IP_NEED_SIZE; 
  
   SELECT COUNT(*) INTO OP_ROWCOUNT FROM (
    SELECT * FROM(
     SELECT T.*,ROWNUM RN FROM 
      (SELECT * FROM ca_simple_food
      WHERE FOOD_NAME LIKE '%'||IP_KEYWORDS||'%'
      ORDER BY MARK_VALUE DESC)
     T
   )
 ) 
 WHERE RN <= IP_NEED_SIZE; 

  
	  
	OP_SEL_CODE:=1;  
	OP_MSG:='';
  EXCEPTION 
   WHEN NO_DATA_FOUND THEN
    BEGIN
       OP_SEL_CODE:=0;
	   OP_ROWCOUNT:=-1;
	   OP_MSG:='没有找到推荐数据';
	END;   
   WHEN OTHERS THEN
  BEGIN
       OP_SEL_CODE:=-1;
	   OP_ROWCOUNT:=-1;
	   OP_MSG:='msg:'||sqlerrm||'';
	END;
END ;
END CA_PKG_SIMPLE_FOOD;

/
--------------------------------------------------------
--  DDL for Package Body CA_RUNTIME_ANAL_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_RUNTIME_ANAL_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_OBJECT_NAME IN CA_RUNTIME_ANAL.OBJECT_NAME%type DEFAULT NULL ,
    p_RECORD_ID   IN CA_RUNTIME_ANAL.RECORD_ID%type ,
    p_COUNT_TIME  IN CA_RUNTIME_ANAL.COUNT_TIME%type ,
    p_OBJECT_TYPE IN CA_RUNTIME_ANAL.OBJECT_TYPE%type ,
    p_AVER_TIME   IN CA_RUNTIME_ANAL.AVER_TIME%type DEFAULT NULL ,
    p_EXE_TIMES   IN CA_RUNTIME_ANAL.EXE_TIMES%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_RUNTIME_ANAL
    (
      OBJECT_NAME ,
      RECORD_ID ,
      COUNT_TIME ,
      OBJECT_TYPE ,
      AVER_TIME ,
      EXE_TIMES
    )
    VALUES
    (
      p_OBJECT_NAME ,
      p_RECORD_ID ,
      p_COUNT_TIME ,
      p_OBJECT_TYPE ,
      p_AVER_TIME ,
      p_EXE_TIMES
    );
END;
-- update
PROCEDURE upd
  (
    p_OBJECT_NAME IN CA_RUNTIME_ANAL.OBJECT_NAME%type DEFAULT NULL ,
    p_RECORD_ID   IN CA_RUNTIME_ANAL.RECORD_ID%type ,
    p_COUNT_TIME  IN CA_RUNTIME_ANAL.COUNT_TIME%type ,
    p_OBJECT_TYPE IN CA_RUNTIME_ANAL.OBJECT_TYPE%type ,
    p_AVER_TIME   IN CA_RUNTIME_ANAL.AVER_TIME%type DEFAULT NULL ,
    p_EXE_TIMES   IN CA_RUNTIME_ANAL.EXE_TIMES%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_RUNTIME_ANAL
  SET OBJECT_NAME = p_OBJECT_NAME ,
    RECORD_ID     = p_RECORD_ID ,
    COUNT_TIME    = p_COUNT_TIME ,
    OBJECT_TYPE   = p_OBJECT_TYPE ,
    AVER_TIME     = p_AVER_TIME ,
    EXE_TIMES     = p_EXE_TIMES
  WHERE ;
END;
-- del
PROCEDURE del(
  )
IS
BEGIN
  DELETE FROM CA_RUNTIME_ANAL WHERE ;
END;
END CA_RUNTIME_ANAL_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_SIMPLE_FOOD_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_SIMPLE_FOOD_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_FOOD_CATEGORY_ID IN CA_SIMPLE_FOOD.FOOD_CATEGORY_ID%type DEFAULT NULL ,
    p_WORSE_MARK       IN CA_SIMPLE_FOOD.WORSE_MARK%type DEFAULT NULL ,
    p_MARK_VALUE       IN CA_SIMPLE_FOOD.MARK_VALUE%type DEFAULT NULL ,
    p_RECORD_ID        IN CA_SIMPLE_FOOD.RECORD_ID%type ,
    p_FOOD_TYPE_ID     IN CA_SIMPLE_FOOD.FOOD_TYPE_ID%type DEFAULT NULL ,
    p_FOOD_IMG         IN CA_SIMPLE_FOOD.FOOD_IMG%type DEFAULT NULL ,
    p_FOOD_PRICE       IN CA_SIMPLE_FOOD.FOOD_PRICE%type DEFAULT NULL ,
    p_MERCHANT_ID      IN CA_SIMPLE_FOOD.MERCHANT_ID%type ,
    p_GOOD_MARK        IN CA_SIMPLE_FOOD.GOOD_MARK%type DEFAULT NULL ,
    p_FOOD_NAME        IN CA_SIMPLE_FOOD.FOOD_NAME%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO CA_SIMPLE_FOOD
    (
      FOOD_CATEGORY_ID ,
      WORSE_MARK ,
      MARK_VALUE ,
      RECORD_ID ,
      FOOD_TYPE_ID ,
      FOOD_IMG ,
      FOOD_PRICE ,
      MERCHANT_ID ,
      GOOD_MARK ,
      FOOD_NAME
    )
    VALUES
    (
      p_FOOD_CATEGORY_ID ,
      p_WORSE_MARK ,
      p_MARK_VALUE ,
      p_RECORD_ID ,
      p_FOOD_TYPE_ID ,
      p_FOOD_IMG ,
      p_FOOD_PRICE ,
      p_MERCHANT_ID ,
      p_GOOD_MARK ,
      p_FOOD_NAME
    );
END;
-- update
PROCEDURE upd
  (
    p_FOOD_CATEGORY_ID IN CA_SIMPLE_FOOD.FOOD_CATEGORY_ID%type DEFAULT NULL ,
    p_WORSE_MARK       IN CA_SIMPLE_FOOD.WORSE_MARK%type DEFAULT NULL ,
    p_MARK_VALUE       IN CA_SIMPLE_FOOD.MARK_VALUE%type DEFAULT NULL ,
    p_RECORD_ID        IN CA_SIMPLE_FOOD.RECORD_ID%type ,
    p_FOOD_TYPE_ID     IN CA_SIMPLE_FOOD.FOOD_TYPE_ID%type DEFAULT NULL ,
    p_FOOD_IMG         IN CA_SIMPLE_FOOD.FOOD_IMG%type DEFAULT NULL ,
    p_FOOD_PRICE       IN CA_SIMPLE_FOOD.FOOD_PRICE%type DEFAULT NULL ,
    p_MERCHANT_ID      IN CA_SIMPLE_FOOD.MERCHANT_ID%type ,
    p_GOOD_MARK        IN CA_SIMPLE_FOOD.GOOD_MARK%type DEFAULT NULL ,
    p_FOOD_NAME        IN CA_SIMPLE_FOOD.FOOD_NAME%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_SIMPLE_FOOD
  SET FOOD_CATEGORY_ID = p_FOOD_CATEGORY_ID ,
    WORSE_MARK         = p_WORSE_MARK ,
    MARK_VALUE         = p_MARK_VALUE ,
    FOOD_TYPE_ID       = p_FOOD_TYPE_ID ,
    FOOD_IMG           = p_FOOD_IMG ,
    FOOD_PRICE         = p_FOOD_PRICE ,
    MERCHANT_ID        = p_MERCHANT_ID ,
    GOOD_MARK          = p_GOOD_MARK ,
    FOOD_NAME          = p_FOOD_NAME
  WHERE RECORD_ID      = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN CA_SIMPLE_FOOD.RECORD_ID%type )
IS
BEGIN
  DELETE FROM CA_SIMPLE_FOOD WHERE RECORD_ID = p_RECORD_ID;
END;

PROCEDURE CHECK_NAME(
	IP_FOOD_NAME IN CA_SIMPLE_FOOD.FOOD_NAME%TYPE,
	IP_USER_ID IN CA_MERCHANT.LOGIN_ID%TYPE,
	OP_CHECK_CODE OUT NUMBER
)
IS
	V_COUNT NUMBER(1,0);
BEGIN
		
    SELECT COUNT(*) INTO V_COUNT 
		FROM CA_SIMPLE_FOOD
		WHERE FOOD_NAME=IP_FOOD_NAME
    AND MERCHANT_ID=IP_USER_ID
    ;
		
		IF V_COUNT =  0 THEN
			OP_CHECK_CODE:=1;
		ELSE
			OP_CHECK_CODE:=0;
		END IF;
END;
PROCEDURE PAGE_FOOD(
    IP_PAGE_INDEX IN NUMBER,--索引
    IP_PAGE_SIZE  IN NUMBER,--页面大小
    IP_QUERY_STATE IN NUMBER,--是否启用查询
    IP_TYPE_ID		IN CA_SIMPLE_FOOD.FOOD_TYPE_ID%TYPE,--类型
    IP_CATEGORY_ID IN CA_SIMPLE_FOOD.FOOD_CATEGORY_ID%TYPE,--菜系
    IP_MERCHANT_ID IN CA_SIMPLE_FOOD.MERCHANT_ID%TYPE,--商家ID
    IP_KEYWORDS IN NVARCHAR2,--关键字
    SELECT_RESULT OUT SYS_REFCURSOR,--查询结果
    OP_ROWCOUNT OUT NUMBER ,--数据量
    OP_CODE OUT NUMBER  --操作代码
)
IS
	e_user_not_exist_exception exception;--用户不存在
	e_user_lock_exception exception;--用户被锁定
	e_lack_permission_exception exception;--用户权限缺失
	
	v_user_type number(1,0)   default 0;
	v_user_count number(1,0)  default 0;
	v_lock_status number(1,0) default 0;
	V_CUR_PAGE NUMBER;
BEGIN
		
	select count(*) into v_user_count  from CA_MERCHANT	where login_id = IP_MERCHANT_ID;
	if v_user_count=0 then
		raise e_user_not_exist_exception;
	end if;
		
	select STATUS,MERCHANT_TYPE into v_lock_status,v_user_type from CA_MERCHANT	where login_id = IP_MERCHANT_ID;
	if v_lock_status=0 then
		raise e_user_lock_exception;
	end if;
	
	V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	
	if v_user_type <> 2 then
		raise e_lack_permission_exception;
	end if;
	
	if IP_QUERY_STATE = 1 then
		BEGIN
		select  COUNT(*) INTO OP_ROWCOUNT
				from CA_SIMPLE_FOOD,ca_detail_food,ca_food_category,ca_food_type
				WHERE ca_simple_food.record_id = ca_detail_food.record_id 
				  AND ca_simple_food.food_category_id = ca_food_category.category_id 
				  AND ca_simple_food.food_type_id =ca_food_type.type_id  
				  AND ca_simple_food.merchant_id=IP_MERCHANT_ID
				  AND ca_simple_food.food_category_id=IP_CATEGORY_ID
				  AND ca_simple_food.food_type_id = IP_TYPE_ID
				  AND ca_simple_food.FOOD_NAME LIKE '%'||IP_KEYWORDS||'%';
			
				
				
			OPEN SELECT_RESULT FOR
			  SELECT * FROM ( 
			   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
			   
					select ca_simple_food.RECORD_ID,
					  FOOD_NAME,
					  to_char(FOOD_PRICE,'L999.00') as PRICE,
					  GOOD_MARK,
					  ca_food_category.category_name,
					  ca_food_type.type_name,
					  pub_date,
            food_img
				from CA_SIMPLE_FOOD,ca_detail_food,ca_food_category,ca_food_type
				WHERE ca_simple_food.record_id = ca_detail_food.record_id 
				  AND ca_simple_food.food_category_id = ca_food_category.category_id 
				  AND ca_simple_food.food_type_id =ca_food_type.type_id  
				  AND ca_simple_food.merchant_id=IP_MERCHANT_ID
				 -- AND ca_simple_food.food_category_id=IP_CATEGORY_ID
				  AND ca_simple_food.food_type_id = IP_TYPE_ID
				  AND ca_simple_food.FOOD_NAME LIKE '%'||IP_KEYWORDS||'%'
				ORDER BY ca_detail_food.pub_date DESC
				 ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);
		END;
	elsif IP_QUERY_STATE = 0 then
	
		BEGIN
		
		
			select  
      COUNT(*) INTO OP_ROWCOUNT
	from CA_SIMPLE_FOOD,ca_detail_food,ca_food_category,ca_food_type
	WHERE ca_simple_food.record_id = ca_detail_food.record_id 
	  AND ca_simple_food.food_category_id = ca_food_category.category_id 
	  AND ca_simple_food.food_type_id =ca_food_type.type_id  
	  AND ca_simple_food.merchant_id=IP_MERCHANT_ID
	ORDER BY ca_detail_food.pub_date DESC;
	
	
			 OPEN SELECT_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
		select ca_simple_food.RECORD_ID,
      FOOD_NAME,
      to_char(FOOD_PRICE,'L999.00') as PRICE,
      GOOD_MARK,
      ca_food_category.category_name,
      ca_food_type.type_name,
      pub_date,
      food_img
	from CA_SIMPLE_FOOD,ca_detail_food,ca_food_category,ca_food_type
	WHERE ca_simple_food.record_id = ca_detail_food.record_id 
	  AND ca_simple_food.food_category_id = ca_food_category.category_id 
	  AND ca_simple_food.food_type_id =ca_food_type.type_id  
	  AND ca_simple_food.merchant_id=IP_MERCHANT_ID
	ORDER BY ca_detail_food.pub_date DESC
      

   ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);
		
		END;
		  
	else
		null;
	end if;	
 OP_CODE:=1;
	
exception
	when 	e_user_not_exist_exception THEN
				OP_CODE:=-1;	
	when 	e_user_lock_exception THEN
				OP_CODE:=-2;
	when 	e_lack_permission_exception THEN
				OP_CODE:=-3;
	when 	no_data_found THEN
				OP_CODE:=0;
	when 	others THEN
				OP_CODE:=-5;
END;


PROCEDURE UPDATE_PRICE(
	IP_FOOD_ID IN NUMBER,--食品ID
	IP_FOOD_PRICE IN NUMBER,--新的价格
	OP_MSG  OUT NVARCHAR2--更新消息
)
AS
BEGIN
	UPDATE CA_SIMPLE_FOOD 
	SET 
		FOOD_PRICE = IP_FOOD_PRICE
	WHERE
		RECORD_ID = IP_FOOD_ID;
		
	OP_MSG:='更新成功';

EXCEPTION 
		WHEN OTHERS THEN
		OP_MSG:='更新失败{code='||sqlcode||' errmsg='||sqlerrm||'}';
		
END;
PROCEDURE SEL_FOOD(
	IP_MERCHANT_ID 		IN 			NVARCHAR2,
	IP_REC_ID 			IN 			NUMBER,
    SELECT_RESULT 		OUT 		SYS_REFCURSOR,--查询结果
    OP_CODE 			OUT 		NUMBER,---操作代码
    OP_MSG 				OUT 		NVARCHAR2
)
AS
	E_USER_NOT_EXIST_EXCEPTION 	EXCEPTION;--用户不存在
	E_USER_LOCK_EXCEPTION      	EXCEPTION;--用户被锁定
	E_LACK_PERMISSION_EXCEPTION EXCEPTION;--用户权限缺失
	
	V_USER_TYPE   NUMBER(1,0)   DEFAULT 0;
	V_USER_COUNT  NUMBER(1,0)   DEFAULT 0;
	V_LOCK_STATUS NUMBER(1,0)   DEFAULT 0;
BEGIN
	SELECT COUNT(*) INTO V_USER_COUNT  FROM CA_MERCHANT	WHERE LOGIN_ID = IP_MERCHANT_ID;
	IF V_USER_COUNT=0 THEN
		RAISE E_USER_NOT_EXIST_EXCEPTION;
	END IF;
		
	SELECT STATUS,MERCHANT_TYPE INTO V_LOCK_STATUS,V_USER_TYPE FROM CA_MERCHANT	WHERE LOGIN_ID = IP_MERCHANT_ID;
	IF V_LOCK_STATUS=0 THEN
		RAISE E_USER_LOCK_EXCEPTION;
	END IF;
	
	IF V_USER_TYPE =5 THEN
		RAISE E_LACK_PERMISSION_EXCEPTION;
	END IF;
	
	OPEN SELECT_RESULT FOR 
		SELECT 	CA_SIMPLE_FOOD.RECORD_ID,
				FOOD_NAME,
				NVL(FOOD_PRICE,0) 			AS PRICE,
				CA_FOOD_CATEGORY.CATEGORY_NAME,
				CA_FOOD_TYPE.TYPE_NAME,
				PUB_DATE,
				FOOD_INTRODUCE
		FROM 
				CA_SIMPLE_FOOD,
				CA_DETAIL_FOOD,
				CA_FOOD_CATEGORY,
				CA_FOOD_TYPE
		WHERE 
				CA_SIMPLE_FOOD.RECORD_ID 		= 	CA_DETAIL_FOOD.RECORD_ID 				AND 
				CA_SIMPLE_FOOD.FOOD_CATEGORY_ID = 	CA_FOOD_CATEGORY.CATEGORY_ID 		AND 
				CA_SIMPLE_FOOD.FOOD_TYPE_ID		=	CA_FOOD_TYPE.TYPE_ID 					AND 
				CA_SIMPLE_FOOD.MERCHANT_ID		=	IP_MERCHANT_ID							AND
				CA_SIMPLE_FOOD.RECORD_ID 		= 	IP_REC_ID
		;

		
	OP_CODE:=1;	
		
EXCEPTION
	WHEN 	E_USER_NOT_EXIST_EXCEPTION THEN
	
			BEGIN
				OP_MSG:='用户不存在';
				OP_CODE:=-1;
			END;			
	WHEN 	E_USER_LOCK_EXCEPTION THEN
			BEGIN
				OP_MSG:='用户被锁定';
				OP_CODE:=-2;
			END;
	WHEN 	E_LACK_PERMISSION_EXCEPTION THEN
		BEGIN
				OP_MSG:='用户缺失权限';
				OP_CODE:=-3;
		END;
	WHEN 	NO_DATA_FOUND THEN	
		BEGIN
				OP_MSG:='没有找到数据';
				OP_CODE:=-4;
		END;
	WHEN 	OTHERS THEN
		BEGIN
				OP_CODE:=-5;
				OP_MSG:='操作失败{CODE='||SQLCODE||' MSG='||SQLERRM||'}';
		END;
END;

PROCEDURE UPDATE_FOOD(
	IP_MERCHANT_ID 		IN 			NVARCHAR2,
	IP_REC_ID 			IN 			NUMBER,
	IP_TYPE_ID			IN 			NUMBER,
	IP_CATEGORY_ID		IN 			NUMBER,
	IP_FOOD_PRICE		IN 			NUMBER,
	IP_FOOD_DESC		IN 			NVARCHAR2,
    OP_CODE 			OUT 		NUMBER,---操作代码
    OP_MSG 				OUT 		NVARCHAR2
)
AS
	E_USER_NOT_EXIST_EXCEPTION 	EXCEPTION;--用户不存在
	E_USER_LOCK_EXCEPTION      	EXCEPTION;--用户被锁定
	E_LACK_PERMISSION_EXCEPTION EXCEPTION;--用户权限缺失
	
	V_USER_TYPE   NUMBER(1,0)   DEFAULT 0;
	V_USER_COUNT  NUMBER(1,0)   DEFAULT 0;
	V_LOCK_STATUS NUMBER(1,0)   DEFAULT 0;
BEGIN
	SELECT COUNT(*) INTO V_USER_COUNT  FROM CA_MERCHANT	WHERE LOGIN_ID = IP_MERCHANT_ID;
	IF V_USER_COUNT=0 THEN
		RAISE E_USER_NOT_EXIST_EXCEPTION;
	END IF;
		
	SELECT STATUS,MERCHANT_TYPE INTO V_LOCK_STATUS,V_USER_TYPE FROM CA_MERCHANT	WHERE LOGIN_ID = IP_MERCHANT_ID;
	IF V_LOCK_STATUS=0 THEN
		RAISE E_USER_LOCK_EXCEPTION;
	END IF;
	
	IF V_USER_TYPE =5 THEN
		RAISE E_LACK_PERMISSION_EXCEPTION;
	END IF;
		
		BEGIN
		
		 UPDATE CA_SIMPLE_FOOD
		  SET 
			FOOD_CATEGORY_ID   = IP_CATEGORY_ID ,
			FOOD_TYPE_ID       = IP_TYPE_ID ,
			FOOD_PRICE         = IP_FOOD_PRICE 
			
		  WHERE RECORD_ID      = IP_REC_ID 	AND
				MERCHANT_ID	   = IP_MERCHANT_ID
		  ;
		  
		 UPDATE CA_DETAIL_FOOD
		  SET 
		 
			FOOD_INTRODUCE         = IP_FOOD_DESC 
			
		  WHERE RECORD_ID      = IP_REC_ID 
				
		  ;
		
		END;	
	COMMIT;
	
	
OP_CODE:=1;	
		
EXCEPTION
	WHEN 	E_USER_NOT_EXIST_EXCEPTION THEN
	
			BEGIN
				ROLLBACK;
				OP_MSG:='用户不存在';
				OP_CODE:=-1;
			END;			
	WHEN 	E_USER_LOCK_EXCEPTION THEN
			BEGIN
				ROLLBACK;
				OP_MSG:='用户被锁定';
				OP_CODE:=-2;
			END;
	WHEN 	E_LACK_PERMISSION_EXCEPTION THEN
		BEGIN
				ROLLBACK;
				OP_MSG:='用户缺失权限';
				OP_CODE:=-3;
		END;
	WHEN 	NO_DATA_FOUND THEN	
		BEGIN
				ROLLBACK;
				OP_MSG:='没有找到数据';
				OP_CODE:=-4;
		END;
	WHEN 	OTHERS THEN
		BEGIN
				ROLLBACK;
				OP_CODE:=-5;
				OP_MSG:='操作失败{CODE='||SQLCODE||' MSG='||SQLERRM||'}';
		END;
END;


PROCEDURE DELETE_FOOD(
	IP_MERCHANT_ID 		IN 			NVARCHAR2,
	IP_REC_ID 			IN 			NUMBER,
	OP_CODE 			OUT 		NUMBER,---操作代码
    OP_MSG 				OUT 		NVARCHAR2
)
AS
	E_USER_NOT_EXIST_EXCEPTION 	EXCEPTION;--用户不存在
	E_USER_LOCK_EXCEPTION      	EXCEPTION;--用户被锁定
	E_LACK_PERMISSION_EXCEPTION EXCEPTION;--用户权限缺失
	
	V_USER_TYPE   NUMBER(1,0)   DEFAULT 0;
	V_USER_COUNT  NUMBER(1,0)   DEFAULT 0;
	V_LOCK_STATUS NUMBER(1,0)   DEFAULT 0;
BEGIN

	SELECT COUNT(*) INTO V_USER_COUNT  FROM CA_MERCHANT	WHERE LOGIN_ID = IP_MERCHANT_ID;
	IF V_USER_COUNT=0 THEN
		RAISE E_USER_NOT_EXIST_EXCEPTION;
	END IF;
		
	SELECT STATUS,MERCHANT_TYPE INTO V_LOCK_STATUS,V_USER_TYPE FROM CA_MERCHANT	WHERE LOGIN_ID = IP_MERCHANT_ID;
	IF V_LOCK_STATUS=0 THEN
		RAISE E_USER_LOCK_EXCEPTION;
	END IF;
	
	IF V_USER_TYPE =5 THEN
		RAISE E_LACK_PERMISSION_EXCEPTION;
	END IF;
	
	BEGIN
		DELETE FROM CA_DETAIL_FOOD WHERE RECORD_ID	=	IP_REC_ID;
		DELETE FROM CA_SIMPLE_FOOD WHERE RECORD_ID  =	IP_REC_ID;
		OP_CODE:=1;
	END;
		
		COMMIT;
	
EXCEPTION
	WHEN 	E_USER_NOT_EXIST_EXCEPTION THEN
	
			BEGIN
				ROLLBACK;
				OP_MSG:='用户不存在';
				OP_CODE:=-1;
			END;			
	WHEN 	E_USER_LOCK_EXCEPTION THEN
			BEGIN
				ROLLBACK;
				OP_MSG:='用户被锁定';
				OP_CODE:=-2;
			END;
	WHEN 	E_LACK_PERMISSION_EXCEPTION THEN
		BEGIN
				ROLLBACK;
				OP_MSG:='用户缺失权限';
				OP_CODE:=-3;
		END;
	WHEN 	NO_DATA_FOUND THEN	
		BEGIN
				ROLLBACK;
				OP_MSG:='没有找到数据';
				OP_CODE:=-4;
		END;
	WHEN 	OTHERS THEN
		BEGIN
				ROLLBACK;
				OP_CODE:=-5;
				OP_MSG:='操作失败{CODE='||SQLCODE||' MSG='||SQLERRM||'}';
		END;	

END ;



END CA_SIMPLE_FOOD_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CA_SITE_COUNT_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CA_SITE_COUNT_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_SITE_NAME IN CA_SITE_COUNT.SITE_NAME%type ,
    p_TOTAL     IN CA_SITE_COUNT.TOTAL%type DEFAULT NULL )
IS
BEGIN
  INSERT INTO CA_SITE_COUNT
    ( SITE_NAME ,TOTAL
    ) VALUES
    ( p_SITE_NAME ,p_TOTAL
    );
END;
-- update
PROCEDURE upd
  (
    p_SITE_NAME IN CA_SITE_COUNT.SITE_NAME%type ,
    p_TOTAL     IN CA_SITE_COUNT.TOTAL%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE CA_SITE_COUNT SET TOTAL = p_TOTAL WHERE SITE_NAME = p_SITE_NAME;
END;
-- del
PROCEDURE del(
    p_SITE_NAME IN CA_SITE_COUNT.SITE_NAME%type )
IS
BEGIN
  DELETE FROM CA_SITE_COUNT WHERE SITE_NAME = p_SITE_NAME;
END;


PROCEDURE SEL_COUNT
  (
    IP_SITE_NAME IN CA_SITE_COUNT.SITE_NAME%type,
    OP_TOTAL OUT CA_SITE_COUNT.TOTAL%type 
  )
  IS
  
  BEGIN
    SELECT TOTAL INTO OP_TOTAL FROM CA_SITE_COUNT WHERE SITE_NAME =IP_SITE_NAME;
  
  EXCEPTION 
  WHEN NO_DATA_FOUND THEN
    OP_TOTAL:=0;
  WHEN OTHERS THEN
   OP_TOTAL:=-1;
  
  END;
END CA_SITE_COUNT_tapi;

/
--------------------------------------------------------
--  DDL for Package Body CHAT_PKG_USER
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."CHAT_PKG_USER" 
IS
/*===================--LOAD USER============================================================*/
  
  PROCEDURE LOAD_USER(
    IP_LOGIN_ID IN NVARCHAR2,
    OP_SELECT_RESULT OUT SYS_REFCURSOR ,
    OP_OPERATE_CODE OUT NUMBER
  )
  IS
  BEGIN
    
       OP_SELECT_RESULT  IS 
      SELECT * FROM COMMON_USER@ca t1;
    --  WHERE t1."LOGIN_ID" = IP_LOGIN_ID;
      OP_OPERATE_CODE:=1;
      
     EXCEPTION 
     WHEN NO_DATA_FOUND THEN
        OP_OPERATE_CODE:=0;
     WHEN OTHERS THEN
        OP_OPERATE_CODE:=-1;
  END LOAD_USER;
 /********************************************************************************************/ 
END CHAT_PKG_USER;

/
--------------------------------------------------------
--  DDL for Package Body COMMON_ACTIVITY_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."COMMON_ACTIVITY_TAPI" 
IS
  -- insert
PROCEDURE ins(
  p_PUB_CONTENT IN COMMON_ACTIVITY.PUB_CONTENT%type DEFAULT NULL ,
    p_PUB_IP      IN COMMON_ACTIVITY.PUB_IP%type DEFAULT NULL ,
 --   p_PUB_DATE    IN COMMON_ACTIVITY.PUB_DATE%type DEFAULT NULL ,
    p_PUB_TITLE   IN COMMON_ACTIVITY.PUB_TITLE%type DEFAULT NULL ,
 --   p_RECORD_ID   IN COMMON_ACTIVITY.RECORD_ID%type 
    p_notify_user in number,
    p_U_LOGINID   IN COMMON_ACTIVITY.U_LOGINID%type DEFAULT NULL,
    op_op_code out number)
IS
t_next_id   COMMON_ACTIVITY.RECORD_ID%type;
BEGIN
   t_next_id :=SEQ_ACTIVTTY_ID.nextval;
  INSERT
  INTO COMMON_ACTIVITY
    (
      PUB_CONTENT ,
      PUB_IP ,
      PUB_DATE ,
      PUB_TITLE ,
      RECORD_ID ,
      U_LOGINID
    )
    VALUES
    (
      p_PUB_CONTENT ,
      p_PUB_IP ,
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi'),
      p_PUB_TITLE ,
      t_next_id ,
      p_U_LOGINID
    );
    --提醒用户
    if p_notify_user = 1 then
      begin
         CA_MESSAGES_tapi.INS(
              6,
              '*',
              p_PUB_TITLE,
              t_next_id
            );
      
      end;
    end if;
    
    commit;
        op_op_code:=1;
exception
  when others then
    op_op_code:=-1;
END;
-- update
PROCEDURE upd
  (
    p_PUB_CONTENT IN COMMON_ACTIVITY.PUB_CONTENT%type DEFAULT NULL ,
    p_PUB_IP      IN COMMON_ACTIVITY.PUB_IP%type DEFAULT NULL ,
    p_PUB_DATE    IN COMMON_ACTIVITY.PUB_DATE%type DEFAULT NULL ,
    p_PUB_TITLE   IN COMMON_ACTIVITY.PUB_TITLE%type DEFAULT NULL ,
    p_RECORD_ID   IN COMMON_ACTIVITY.RECORD_ID%type ,
    p_U_LOGINID   IN COMMON_ACTIVITY.U_LOGINID%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE COMMON_ACTIVITY
  SET PUB_CONTENT = p_PUB_CONTENT ,
    PUB_IP        = p_PUB_IP ,
    PUB_DATE      = p_PUB_DATE ,
    PUB_TITLE     = p_PUB_TITLE ,
    U_LOGINID     = p_U_LOGINID
  WHERE RECORD_ID = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN COMMON_ACTIVITY.RECORD_ID%type )
IS
BEGIN
  DELETE FROM COMMON_ACTIVITY WHERE RECORD_ID = p_RECORD_ID;
END;
END COMMON_ACTIVITY_tapi;

/
--------------------------------------------------------
--  DDL for Package Body COMMON_MESSAGE_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."COMMON_MESSAGE_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_PUB_IP      IN COMMON_MESSAGE.PUB_IP%type DEFAULT NULL ,
    p_PUB_DATE    IN COMMON_MESSAGE.PUB_DATE%type DEFAULT NULL ,
    p_RECORD_ID   IN COMMON_MESSAGE.RECORD_ID%type ,
    p_MSG_CONTENT IN COMMON_MESSAGE.MSG_CONTENT%type DEFAULT NULL ,
    p_MSG_TITLE   IN COMMON_MESSAGE.MSG_TITLE%type DEFAULT NULL ,
    p_PUB_AUTHOR  IN COMMON_MESSAGE.PUB_AUTHOR%type DEFAULT NULL ,
    p_MSG_TYPE    IN COMMON_MESSAGE.MSG_TYPE%type DEFAULT NULL ,
    p_MSG_METHOD  IN COMMON_MESSAGE.MSG_METHOD%type DEFAULT NULL ,
    p_PUSH_TYPE   IN COMMON_MESSAGE.PUSH_TYPE%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO COMMON_MESSAGE
    (
      PUB_IP ,
      PUB_DATE ,
      RECORD_ID ,
      MSG_CONTENT ,
      MSG_TITLE ,
      PUB_AUTHOR ,
      MSG_TYPE ,
      MSG_METHOD ,
      PUSH_TYPE
    )
    VALUES
    (
      p_PUB_IP ,
      p_PUB_DATE ,
      p_RECORD_ID ,
      p_MSG_CONTENT ,
      p_MSG_TITLE ,
      p_PUB_AUTHOR ,
      p_MSG_TYPE ,
      p_MSG_METHOD ,
      p_PUSH_TYPE
    );
END;
-- update
PROCEDURE upd
  (
    p_PUB_IP      IN COMMON_MESSAGE.PUB_IP%type DEFAULT NULL ,
    p_PUB_DATE    IN COMMON_MESSAGE.PUB_DATE%type DEFAULT NULL ,
    p_RECORD_ID   IN COMMON_MESSAGE.RECORD_ID%type ,
    p_MSG_CONTENT IN COMMON_MESSAGE.MSG_CONTENT%type DEFAULT NULL ,
    p_MSG_TITLE   IN COMMON_MESSAGE.MSG_TITLE%type DEFAULT NULL ,
    p_PUB_AUTHOR  IN COMMON_MESSAGE.PUB_AUTHOR%type DEFAULT NULL ,
    p_MSG_TYPE    IN COMMON_MESSAGE.MSG_TYPE%type DEFAULT NULL ,
    p_MSG_METHOD  IN COMMON_MESSAGE.MSG_METHOD%type DEFAULT NULL ,
    p_PUSH_TYPE   IN COMMON_MESSAGE.PUSH_TYPE%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE COMMON_MESSAGE
  SET PUB_IP      = p_PUB_IP ,
    PUB_DATE      = p_PUB_DATE ,
    MSG_CONTENT   = p_MSG_CONTENT ,
    MSG_TITLE     = p_MSG_TITLE ,
    PUB_AUTHOR    = p_PUB_AUTHOR ,
    MSG_TYPE      = p_MSG_TYPE ,
    MSG_METHOD    = p_MSG_METHOD ,
    PUSH_TYPE     = p_PUSH_TYPE
  WHERE RECORD_ID = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN COMMON_MESSAGE.RECORD_ID%type )
IS
BEGIN
  DELETE FROM COMMON_MESSAGE WHERE RECORD_ID = p_RECORD_ID;
END;
END COMMON_MESSAGE_tapi;

/
--------------------------------------------------------
--  DDL for Package Body COMMON_USER_FAV_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."COMMON_USER_FAV_TAPI" 
IS
---1表示订餐收藏
  -- insert
 PROCEDURE ins(
      p_LOGIN_ID IN COMMON_USER_FAV.LOGIN_ID%type DEFAULT NULL ,
      p_ID       IN COMMON_USER_FAV.ID%type DEFAULT NULL ,
      p_IDTYPE   IN COMMON_USER_FAV.IDTYPE%type DEFAULT NULL ,
      p_TITLE    IN COMMON_USER_FAV.TITLE%type DEFAULT NULL,
      OP_OP_CODE OUT NUMBER
      )
IS
  user_lock_exception  exception;
  user_not_exist exception ;
  have_fav_exception exception;
  t_lock_status number(1,0);
  t_user_count number(1,0);
  t_fav_count number(1,0);
BEGIN
    --permisson check
    select count(*) into t_user_count from common_user where login_id =p_LOGIN_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    

    select STATUS into t_lock_status from common_user where login_id = p_LOGIN_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
    select count(*) into t_fav_count from COMMON_USER_FAV where "ID" = p_ID and IDTYPE=p_IDTYPE and  LOGIN_ID =p_LOGIN_ID;
    if t_fav_count <> 0  then
      raise have_fav_exception;
    end if;
  INSERT
  INTO COMMON_USER_FAV
    (
      LOGIN_ID ,
      DATELINE ,
      "ID" ,
      IDTYPE ,
      TITLE
    )
    VALUES
    (
      p_LOGIN_ID ,
     TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi'),
      p_ID ,
      p_IDTYPE ,
      p_TITLE
    );
    OP_OP_CODE:=1;
    
  exception
  when user_not_exist then
    OP_OP_CODE:=-2;
  when   user_lock_exception then
  OP_OP_CODE:=-3;
  when have_fav_exception then
   OP_OP_CODE:=-4;
  when others then
   OP_OP_CODE:=-1; 
   
END;
-- update
PROCEDURE upd
  (
    p_LOGIN_ID IN COMMON_USER_FAV.LOGIN_ID%type DEFAULT NULL ,
    p_DATELINE IN COMMON_USER_FAV.DATELINE%type DEFAULT NULL ,
    p_FAVID    IN COMMON_USER_FAV.FAVID%type ,
    p_ID       IN COMMON_USER_FAV.ID%type DEFAULT NULL ,
    p_IDTYPE   IN COMMON_USER_FAV.IDTYPE%type DEFAULT NULL ,
    p_TITLE    IN COMMON_USER_FAV.TITLE%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE COMMON_USER_FAV
  SET LOGIN_ID = p_LOGIN_ID ,
    DATELINE   = p_DATELINE ,
    ID         = p_ID ,
    IDTYPE     = p_IDTYPE ,
    TITLE      = p_TITLE
  WHERE FAVID  = p_FAVID;
END;
-- del
PROCEDURE del(
    p_FAVID IN COMMON_USER_FAV.FAVID%type )
IS
BEGIN
  DELETE FROM COMMON_USER_FAV WHERE FAVID = p_FAVID;
END;


 PROCEDURE ISFAV(
    IP_USER_ID IN NVARCHAR2,
    IP_RECORD_ID IN NUMBER,
    IP_TYPE_ID IN NUMBER,
    OP_IS_FAV OUT NUMBER,
    OP_OP_CODE OUT NUMBER
  )
  IS
  user_lock_exception  exception;
  user_not_exist exception ;
  t_lock_status number(1,0);
  t_user_count number(1,0);
  t_fav_count number(1,0);
  BEGIN
     select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
   select count(*) into t_fav_count from COMMON_USER_FAV where "ID" = IP_RECORD_ID and IDTYPE=IP_TYPE_ID and LOGIN_ID =IP_USER_ID ;
    if t_fav_count = 0  then
     OP_IS_FAV:=1;
    elsif t_fav_count=1 then
      OP_IS_FAV:=2;
    end if;
     OP_OP_CODE:=1;
     
     
     exception
  when user_not_exist then
    OP_OP_CODE:=-2;
  when   user_lock_exception then
    OP_OP_CODE:=-3;
 
  when others then
   OP_OP_CODE:=-1; 
   
  END;
  
  
  
  PROCEDURE ISFAV_V2(
    IP_USER_ID IN NVARCHAR2,
    IP_RECORD_ID IN NUMBER,
    IP_TYPE_ID IN NUMBER,
    OP_IS_FAV OUT NUMBER,
    OP_OP_CODE OUT NUMBER
  )
  IS
  user_lock_exception  exception;
  user_not_exist exception ;
  t_lock_status number(1,0);
  t_user_count number(1,0);
  t_fav_count number(1,0);
  BEGIN
     select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
   select count(*) into t_fav_count from COMMON_USER_FAV where "ID" = IP_RECORD_ID and IDTYPE=IP_TYPE_ID and LOGIN_ID =IP_USER_ID ;
    if t_fav_count = 0  then
     OP_IS_FAV:=1;
    elsif t_fav_count=1 then
      OP_IS_FAV:=2;
    end if;
     OP_OP_CODE:=1;
     
     
     exception
  when user_not_exist then
    OP_OP_CODE:=-2;
  when   user_lock_exception then
    OP_OP_CODE:=-3;
 
  when others then
   OP_OP_CODE:=-1; 
   
  END;
  
  --cancel fav
    PROCEDURE CANCEL_FAV(
        IP_USER_ID IN NVARCHAR2,
        IP_RECORD_ID IN NUMBER,
        IP_TYPE_ID IN NUMBER,
        OP_OP_C0DE OUT NUMBER
    )
    is
    user_lock_exception  exception;
    user_not_exist exception ;
    no_fav_exception exception;
    t_lock_status number(1,0);
    t_user_count number(1,0);
    t_fav_count number(1,0);
    begin
    
       --permisson check
    select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
    select count(*) into t_fav_count from COMMON_USER_FAV where "ID" = IP_RECORD_ID and IDTYPE=IP_TYPE_ID and  LOGIN_ID =IP_USER_ID;
    if t_fav_count = 0  then
      raise no_fav_exception;
    end if;
     
     delete from  COMMON_USER_FAV
     where "ID" = IP_RECORD_ID and IDTYPE=IP_TYPE_ID and  LOGIN_ID =IP_USER_ID;
     commit;
     OP_OP_C0DE:=1;
  exception
  when user_not_exist then
    OP_OP_C0DE:=-2;
    rollback;
  when   user_lock_exception then
    OP_OP_C0DE:=-3;
       rollback;
  when no_fav_exception then
    OP_OP_C0DE:=-4;
       rollback;
  when others then
    OP_OP_C0DE:=-1; 
       rollback;
    end;
  
  
  
  
  
  
  
  
   PROCEDURE SEL_FAV_USER(
    IP_PAGE_INDEX IN NUMBER,
    IP_PAGE_SIZE IN NUMBER,
    IP_USER_ID IN NVARCHAR2,
    OP_SELECT_RESULT OUT SYS_REFCURSOR,
    OP_OPERATE_CODE OUT NUMBER
   )
   IS
      user_lock_exception  exception;
      user_not_exist exception ;
      t_lock_status number(1,0);
      t_user_count number(1,0);
      V_CUR_PAGE NUMBER;
   BEGIN
   
        --permisson check
    select count(*) into t_user_count from common_user where login_id =IP_USER_ID;
    if t_user_count < 1   then
      raise user_not_exist;
    end if;
    
    select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
    if  t_lock_status <>0 then
      raise user_lock_exception;
    end if;  
    
     V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
    
     OPEN OP_SELECT_RESULT FOR
  SELECT * FROM ( 
   SELECT * FROM (SELECT T.*,ROWNUM RN FROM (
   
 
      SELECT * FROM COMMON_USER_FAV WHERE LOGIN_ID = IP_USER_ID
       and IDTYPE = 1
       ORDER BY DATELINE DESC


   ) T)
  )
  WHERE
  RN >= (V_CUR_PAGE + 1) AND 
  RN <= (V_CUR_PAGE + IP_PAGE_SIZE);

 OP_OPERATE_CODE:=1;
    
    
    exception
  when user_not_exist then
    OP_OPERATE_CODE:=-2;
   when   user_lock_exception then
    OP_OPERATE_CODE:=-3;
  WHEN NO_DATA_FOUND THEN
    OP_OPERATE_CODE:=0;
  when others then
    OP_OPERATE_CODE:=-1; 
    END ;
  
  
  
  
  FUNCTION ISFAV_V3(
    IP_USER_ID IN NVARCHAR2,
    IP_RECORD_ID IN NUMBER,
    IP_TYPE_ID IN NUMBER
  )
  RETURN   NUMBER
  IS
  OP_IS_FAV NUMBER;
  T_FAV_COUNT NUMBER(1,0);
  BEGIN
     
    
   SELECT COUNT(*) INTO T_FAV_COUNT FROM COMMON_USER_FAV WHERE "ID" = IP_RECORD_ID AND IDTYPE=IP_TYPE_ID AND LOGIN_ID =IP_USER_ID ;
    IF T_FAV_COUNT = 0  THEN
     OP_IS_FAV:=1;
    ELSIF T_FAV_COUNT=1 THEN
      OP_IS_FAV:=2;
    END IF;
    
     RETURN OP_IS_FAV;
     
     EXCEPTION
  
  WHEN OTHERS THEN
	OP_IS_FAV:=1;
	RETURN OP_IS_FAV;
  END;
  PROCEDURE INSV2(
      P_LOGIN_ID IN COMMON_USER_FAV.LOGIN_ID%TYPE DEFAULT NULL ,
      P_ID       IN COMMON_USER_FAV.ID%TYPE DEFAULT NULL ,
      P_IDTYPE   IN COMMON_USER_FAV.IDTYPE%TYPE DEFAULT NULL ,
      P_TITLE    IN COMMON_USER_FAV.TITLE%TYPE DEFAULT NULL,
      OP_OP_CODE OUT NUMBER,
	  OP_MSG OUT NVARCHAR2
      )
IS
  USER_LOCK_EXCEPTION  EXCEPTION;
  USER_NOT_EXIST EXCEPTION ;
  HAVE_FAV_EXCEPTION EXCEPTION;
  T_LOCK_STATUS NUMBER(1,0);
  T_USER_COUNT NUMBER(1,0);
  T_FAV_COUNT NUMBER(1,0);
BEGIN
    --PERMISSON CHECK
    SELECT COUNT(*) INTO T_USER_COUNT FROM COMMON_USER WHERE LOGIN_ID =P_LOGIN_ID;
    IF T_USER_COUNT < 1   THEN
      RAISE USER_NOT_EXIST;
    END IF;
    
    SELECT STATUS INTO T_LOCK_STATUS FROM COMMON_USER WHERE LOGIN_ID = P_LOGIN_ID;
    IF  T_LOCK_STATUS <>0 THEN
      RAISE USER_LOCK_EXCEPTION;
    END IF;  
    
    SELECT COUNT(*) INTO T_FAV_COUNT FROM COMMON_USER_FAV WHERE "ID" = P_ID AND IDTYPE=P_IDTYPE AND  LOGIN_ID =P_LOGIN_ID;
    IF T_FAV_COUNT <> 0  THEN
      RAISE HAVE_FAV_EXCEPTION;
    END IF;
  INSERT
  INTO COMMON_USER_FAV
    (
      LOGIN_ID ,
      DATELINE ,
      "ID" ,
      IDTYPE ,
      TITLE
    )
    VALUES
    (
      P_LOGIN_ID ,
      TO_CHAR(SYSDATE(),'YYYY-MM-DD HH24:MI'),
      P_ID ,
      P_IDTYPE ,
      P_TITLE
    );
    OP_OP_CODE:=1;
    OP_MSG:='';
  EXCEPTION
  WHEN USER_NOT_EXIST THEN
	BEGIN
    OP_OP_CODE:=-2;
	OP_MSG:='用户不存在';
	END;
  WHEN   USER_LOCK_EXCEPTION THEN
  begin
  OP_OP_CODE:=-3;
  OP_MSG:='用户被锁定';
  end;
  WHEN HAVE_FAV_EXCEPTION THEN
   begin	
   OP_OP_CODE:=-4;
   OP_MSG:='您已经收藏过了';
   end;
  WHEN OTHERS THEN
	begin
		OP_OP_CODE:=-1; 
		OP_MSG:=''||sqlerrm||'';
    end;
END;


  PROCEDURE CANCEL_FAV_V2(
	IP_USER_ID IN NVARCHAR2,
	IP_RECORD_ID IN NUMBER,
	IP_TYPE_ID IN NUMBER,
	OP_OP_CODE OUT NUMBER,
	OP_MSG	   OUT NVARCHAR2
)
IS
USER_LOCK_EXCEPTION  EXCEPTION;
USER_NOT_EXIST EXCEPTION ;
NO_FAV_EXCEPTION EXCEPTION;
T_LOCK_STATUS NUMBER(1,0);
T_USER_COUNT NUMBER(1,0);
T_FAV_COUNT NUMBER(1,0);
BEGIN

   --PERMISSON CHECK
SELECT COUNT(*) INTO T_USER_COUNT FROM COMMON_USER WHERE LOGIN_ID =IP_USER_ID;
IF T_USER_COUNT < 1   THEN
  RAISE USER_NOT_EXIST;
END IF;

SELECT STATUS INTO T_LOCK_STATUS FROM COMMON_USER WHERE LOGIN_ID = IP_USER_ID;
IF  T_LOCK_STATUS <>0 THEN
  RAISE USER_LOCK_EXCEPTION;
END IF;  

SELECT COUNT(*) INTO T_FAV_COUNT FROM COMMON_USER_FAV WHERE "ID" = IP_RECORD_ID AND IDTYPE=IP_TYPE_ID AND  LOGIN_ID =IP_USER_ID;
IF T_FAV_COUNT = 0  THEN
  RAISE NO_FAV_EXCEPTION;
END IF;
 
 DELETE FROM  COMMON_USER_FAV
 WHERE "ID" = IP_RECORD_ID AND IDTYPE=IP_TYPE_ID AND  LOGIN_ID =IP_USER_ID;
 COMMIT;
 
 OP_OP_CODE:=1;
 OP_MSG:='';
  EXCEPTION
  WHEN USER_NOT_EXIST THEN
	BEGIN
    OP_OP_CODE:=-2;
	OP_MSG:='用户不存在';
	ROLLBACK;
	END;
  WHEN   USER_LOCK_EXCEPTION THEN
  BEGIN
  OP_OP_CODE:=-3;
  OP_MSG:='用户被锁定';
  ROLLBACK;
  END;
  
  WHEN OTHERS THEN
	BEGIN
	OP_OP_CODE:=-1; 
	OP_MSG:=''||SQLERRM||'';
	ROLLBACK;
    END;
END;
END COMMON_USER_FAV_tapi;

/
--------------------------------------------------------
--  DDL for Package Body COMMON_USER_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."COMMON_USER_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_LOGIN_ID         IN COMMON_USER.LOGIN_ID%type ,
    p_REGSTATUS        IN COMMON_USER.REGSTATUS%type DEFAULT NULL ,
    p_CHANNEL_ID       IN COMMON_USER.CHANNEL_ID%type DEFAULT NULL ,
    p_GROUPID          IN COMMON_USER.GROUPID%type DEFAULT NULL ,
    p_USER_APP_ID      IN COMMON_USER.USER_APP_ID%type DEFAULT NULL ,
    p_USER_TYPE        IN COMMON_USER.USER_TYPE%type DEFAULT NULL ,
    p_STATUS           IN COMMON_USER.STATUS%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN COMMON_USER.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_NICKNAME         IN COMMON_USER.NICKNAME%type DEFAULT NULL ,
    p_USER_MOBILE_TYPE IN COMMON_USER.USER_MOBILE_TYPE%type DEFAULT NULL ,
    p_ALLOWADMINCP     IN COMMON_USER.ALLOWADMINCP%type DEFAULT NULL ,
    p_RECORD_ID        IN COMMON_USER.RECORD_ID%type ,
    p_IDNUMBER         IN COMMON_USER.IDNUMBER%type DEFAULT NULL ,
    p_USER_TAGS        IN COMMON_USER.USER_TAGS%type DEFAULT NULL ,
    p_NEWPROMPT        IN COMMON_USER.NEWPROMPT%type DEFAULT NULL ,
    p_NEWPM            IN COMMON_USER.NEWPM%type DEFAULT NULL ,
    p_LASTTIME         IN COMMON_USER.LASTTIME%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO COMMON_USER
    (
      LOGIN_ID ,
      REGSTATUS ,
      CHANNEL_ID ,
      GROUPID ,
      USER_APP_ID ,
      USER_TYPE ,
      STATUS ,
      ENCRYPTPASSWORD ,
      NICKNAME ,
      USER_MOBILE_TYPE ,
      ALLOWADMINCP ,
      RECORD_ID ,
      IDNUMBER ,
      USER_TAGS ,
      NEWPROMPT ,
      NEWPM ,
      LASTTIME
    )
    VALUES
    (
      p_LOGIN_ID ,
      p_REGSTATUS ,
      p_CHANNEL_ID ,
      p_GROUPID ,
      p_USER_APP_ID ,
      p_USER_TYPE ,
      p_STATUS ,
      p_ENCRYPTPASSWORD ,
      p_NICKNAME ,
      p_USER_MOBILE_TYPE ,
      p_ALLOWADMINCP ,
      p_RECORD_ID ,
      p_IDNUMBER ,
      p_USER_TAGS ,
      p_NEWPROMPT ,
      p_NEWPM ,
      p_LASTTIME
    );
END;
-- update
PROCEDURE upd
  (
    p_LOGIN_ID         IN COMMON_USER.LOGIN_ID%type ,
    p_REGSTATUS        IN COMMON_USER.REGSTATUS%type DEFAULT NULL ,
    p_CHANNEL_ID       IN COMMON_USER.CHANNEL_ID%type DEFAULT NULL ,
    p_GROUPID          IN COMMON_USER.GROUPID%type DEFAULT NULL ,
    p_USER_APP_ID      IN COMMON_USER.USER_APP_ID%type DEFAULT NULL ,
    p_USER_TYPE        IN COMMON_USER.USER_TYPE%type DEFAULT NULL ,
    p_STATUS           IN COMMON_USER.STATUS%type DEFAULT NULL ,
    p_ENCRYPTPASSWORD  IN COMMON_USER.ENCRYPTPASSWORD%type DEFAULT NULL ,
    p_NICKNAME         IN COMMON_USER.NICKNAME%type DEFAULT NULL ,
    p_USER_MOBILE_TYPE IN COMMON_USER.USER_MOBILE_TYPE%type DEFAULT NULL ,
    p_ALLOWADMINCP     IN COMMON_USER.ALLOWADMINCP%type DEFAULT NULL ,
    p_RECORD_ID        IN COMMON_USER.RECORD_ID%type ,
    p_IDNUMBER         IN COMMON_USER.IDNUMBER%type DEFAULT NULL ,
    p_USER_TAGS        IN COMMON_USER.USER_TAGS%type DEFAULT NULL ,
    p_NEWPROMPT        IN COMMON_USER.NEWPROMPT%type DEFAULT NULL ,
    p_NEWPM            IN COMMON_USER.NEWPM%type DEFAULT NULL ,
    p_LASTTIME         IN COMMON_USER.LASTTIME%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE COMMON_USER
  SET REGSTATUS      = p_REGSTATUS ,
    CHANNEL_ID       = p_CHANNEL_ID ,
    GROUPID          = p_GROUPID ,
    USER_APP_ID      = p_USER_APP_ID ,
    USER_TYPE        = p_USER_TYPE ,
    STATUS           = p_STATUS ,
    ENCRYPTPASSWORD  = p_ENCRYPTPASSWORD ,
    NICKNAME         = p_NICKNAME ,
    USER_MOBILE_TYPE = p_USER_MOBILE_TYPE ,
    ALLOWADMINCP     = p_ALLOWADMINCP ,
    RECORD_ID        = p_RECORD_ID ,
    IDNUMBER         = p_IDNUMBER ,
    USER_TAGS        = p_USER_TAGS ,
    NEWPROMPT        = p_NEWPROMPT ,
    NEWPM            = p_NEWPM ,
    LASTTIME         = p_LASTTIME
  WHERE LOGIN_ID     = p_LOGIN_ID;
END;
-- del
PROCEDURE del(
    p_LOGIN_ID IN COMMON_USER.LOGIN_ID%type )
IS
BEGIN
  DELETE FROM COMMON_USER WHERE LOGIN_ID = p_LOGIN_ID;
END;

PROCEDURE REG(
  username in COMMON_USER.LOGIN_ID%type,
  idcard in varchar2,
  reg_ip in varchar2,
  last_ip in varchar2,
  pwd in  COMMON_USER.ENCRYPTPASSWORD%type,
  ip_nickname in COMMON_USER.NICKNAME%type,
  OP_USER OUT SYS_REFCURSOR,
  OP_INS_CODE OUT NUMBER 
)IS
user_not_exist_exception exception;
user_had_reg_exception exception;
id_card_not_exception exception;
invalid_idcard_exception exception;
error_idnumber_exception exception;
t_user_count number(1,0);
t_reg_status number(1,0);
t_idcard COMMON_USER.IDNUMBER%type;

t_tags common_user.USER_TAGS%type;
BEGIN
  --查询是否存在用户
  select count(*) into t_user_count from COMMON_USER where login_id = username;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  
  --用户是否已经注册
  select REGSTATUS into t_reg_status from common_user where  login_id = username;
  if t_reg_status = 0 then
    raise user_had_reg_exception;
  end if;
  
  
  
  
  --判断身份证号是否存在
  select IDNUMBER into t_idcard from common_user where  login_id = username;
  if CA_CHECK_NULL(t_idcard) = 1 then
     raise id_card_not_exception;
  end if; 
  
  --身份证号码是否正确
  if length(t_idcard) <> 18 then
  
      raise invalid_idcard_exception;
  end if; 
  
  --身份证号码匹配
  if substr(t_idcard,length(t_idcard)-3,4) <> idcard  then
       raise error_idnumber_exception;
  end if;
  
  begin
    update COMMON_USER
    set
    ENCRYPTPASSWORD = pwd,
    NICKNAME = ip_nickname,
    REGSTATUS = 0,
    STATUS = 0
    where  login_id = username;
   
   --记录操作
   PROC_RECORD_USER_STATUS(
    username,
    reg_ip,
    last_ip,
    TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi:ss'),
    1
   );
   
   --更新用户标签
   select USER_TAGS into t_tags from common_user  where login_id =username;
     if CA_CHECK_NULL(t_tags) = 1 then
        GEN_TAGS(username);
     end if; 
   
    commit;
  end;
  
  open OP_USER for
  select * from COMMON_USER left join common_user_profile
  on COMMON_USER.login_id = common_user_profile.login_id
  where  COMMON_USER.login_id = username;
  
  OP_INS_CODE:=1;
  
exception   
when   user_not_exist_exception then
  begin
  open OP_USER for
  select '用户不存在' from dual;
  OP_INS_CODE:=-2;
  rollback;
  end;
when    user_had_reg_exception then
  begin
   open OP_USER for
  select '该用户已注册' from dual;
  OP_INS_CODE:=-3;
  rollback;
  end;
when id_card_not_exception then
  begin
   open OP_USER for
  select '身份证号不存在' from dual;
  OP_INS_CODE:=-4;
  rollback;
  end;
when invalid_idcard_exception then
  begin
   open OP_USER for
  select '不合法的身份证号码' from dual;
  OP_INS_CODE:=-5;
  rollback;
  end;
  
when error_idnumber_exception then
 begin
   open OP_USER for
   select '错误的身份证号码' from dual;
  OP_INS_CODE:=-6;
  rollback;
  end;
when others then
  begin
     open OP_USER for
     select '其他错误' from dual;
     OP_INS_CODE:=-7;
     rollback;
  end;
END;

--2010 13 01 02 12
 PROCEDURE GEN_TAGS(
    username in COMMON_USER.LOGIN_ID%type
  )is
  t_college_name COMMON_DEPT.COLLEGE_NAME%type;
  t_coolege_no COMMON_DEPT.COLLEGE_NO%type;
  t_marjor_no COMMON_MAJOR.MAJOR_NO%type;
  t_grade nvarchar2(10);
  tags nvarchar2(400);
  t_marjor_name COMMON_MAJOR.MAJOR_NAME %type;

  t_class_no nvarchar2(30);
  
  begin
    if length(username)=12 then 
        t_coolege_no:= substr(username,5,2);
          dbms_output.put_line('学院号:'||t_coolege_no);
        SELECT COLLEGE_NAME INTO t_college_name FROM COMMON_DEPT WHERE COLLEGE_NO=t_coolege_no;
         dbms_output.put_line('学院名称:'||t_college_name);
     if  CA_CHECK_NULL(t_college_name) <>1 then--学院名称不为空
        t_grade:= substr(username,1,4);
        t_marjor_no:=substr(username,7,2);
       dbms_output.put_line('年纪编号:'||t_grade);
       dbms_output.put_line('专业编号:'||t_marjor_no);
       
       if t_grade = '2010' and t_marjor_no = '01' then--如果是10级，且专业号为13,专业号发生改变
          t_marjor_no:='05';
       end if;
       
       
       SELECT MAJOR_NAME INTO t_marjor_name FROM COMMON_MAJOR WHERE MAJOR_NO=t_marjor_no AND COLLEGE_NO=t_coolege_no;
       
         if  CA_CHECK_NULL(t_marjor_name) <>1 then--专业名称不为空
            t_grade := substr(username,1,4)||'级';
            t_class_no:=substr(username,10,1)||'班';
            
            ---组成TAG
            tags:=tags||t_college_name||',';
            tags:=tags||t_college_name||'_'||t_marjor_name||',';
            tags:=tags||t_college_name||'_'||t_marjor_name||'_'||t_grade||',';
            tags:=tags||t_college_name||'_'||t_marjor_name||'_'||t_grade||'_'||t_class_no;
           
           
           --更新用户TAG
           UPDATE COMMON_USER 
           SET USER_TAGS = tags
           where login_id =username;
           
        end if;
     end if;
         
    end if;
  
  exception
  when others then
  begin
  dbms_output.put_line('exception');
  end;
  
  end;
  
  
  
  
  PROCEDURE login(
    username in COMMON_USER.LOGIN_ID%type,
   pwd in  COMMON_USER.ENCRYPTPASSWORD%type,
   last_ip in varchar2,
   OP_USER OUT SYS_REFCURSOR,
    OP_OP_CODE OUT NUMBER 
)IS
user_not_exist_exception exception ;
not_reg_exception exception;
user_lock_exception exception;
invalid_pwd_exception exception;
t_user_count number(1,0);
t_reg_status number(1,0);
t_lock_status number(1,0);
t_password COMMON_USER.ENCRYPTPASSWORD%type;
t_tags common_user.USER_TAGS%type;
BEGIN
  --查询是否存在用户
  select count(*) into t_user_count from COMMON_USER where login_id = username;
  if t_user_count = 0 then
    raise user_not_exist_exception;
  end if;
  --判断用户是否已经注册
  select REGSTATUS into t_reg_status from common_user where  login_id = username;
  if t_reg_status = -1 then
    raise not_reg_exception;
  end if;
  
  --判断用户是否被锁定
   select STATUS into t_lock_status from common_user where  login_id = username;
  if t_lock_status = -1 then
    raise user_lock_exception;
  end if;
  
  --判定密码是否正确
  select ENCRYPTPASSWORD into t_password from common_user where  login_id = username;
  if t_password <> pwd  then
    raise invalid_pwd_exception;
  end if;
  open OP_USER for 
  select * from common_user left join common_user_profile on common_user.login_id = common_user_profile.login_id where common_user.login_id=username;
 
 --记录用户操作
  PROC_RECORD_USER_STATUS(
    username,
    '',
    last_ip,
    TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi:ss'),
    1
   );
   
    --更新用户标签
   select USER_TAGS into t_tags from common_user  where login_id =username;
     if CA_CHECK_NULL(t_tags) = 1 then
        GEN_TAGS(username);
    end if; 
    OP_OP_CODE:=1;
    
    
 exception   
when   user_not_exist_exception then
  begin
  open OP_USER for
  select '用户不存在' from dual;
  OP_OP_CODE:=-12;
  rollback;
  end;
when    not_reg_exception then
  begin
   open OP_USER for
  select '用户未注册' from dual;
  OP_OP_CODE:=-13;
  rollback;
  end;
when user_lock_exception then
  begin
   open OP_USER for
  select '用户被锁定' from dual;
  OP_OP_CODE:=-14;
  rollback;
  end;
when invalid_pwd_exception then
  begin
   open OP_USER for
  select '错误的密码' from dual;
  OP_OP_CODE:=-15;
  rollback;
  end;
  
 
when others then
  begin
     open OP_USER for
     select '其他错误' from dual;
     OP_OP_CODE:=-17;
     rollback;
  end;   
END;




PROCEDURE CA_QUERY_USER(
	IP_KEYWORDS IN NVARCHAR2,
	IP_USER_ID IN COMMON_USER.LOGIN_ID%TYPE,

	OP_SEL_RESULT OUT SYS_REFCURSOR,
	OP_OP_CODE OUT NUMBER
)

IS
	user_not_exist_exception exception;
	user_not_reg_exception exception;
	user_lock_exception exception;
	t_user_count number(1,0);
	t_reg_status number(1,0);
	t_lock_status number(1,0);
	V_CUR_PAGE NUMBER;

BEGIN
	--PERMISSION CHECK BEGIN
	select count(*) into t_user_count from common_user where login_id = IP_USER_ID;
		  
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user  where login_id = IP_USER_ID;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
	
	-- V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	
	--PERMISSION CHECK END
	
	
	   OPEN OP_SEL_RESULT FOR
  
	  
		 
		SELECT * FROM COMMON_USER LEFT JOIN common_user_profile ON COMMON_USER.LOGIN_ID=common_user_profile.LOGIN_ID
WHERE COMMON_USER.REGSTATUS = 0 AND STATUS = 0 AND ( COMMON_USER.LOGIN_ID LIKE '%'||IP_KEYWORDS||'%' OR COMMON_USER.NICKNAME LIKE '%'||IP_KEYWORDS||'%' )
ORDER BY common_user.login_id;
			 
			 
	
		OP_OP_CODE:=1;
	
exception 
	
	when user_not_exist_exception then
		begin
		OP_OP_CODE:=-1;
		 OPEN OP_SEL_RESULT FOR
		 select '用户不存在' from dual;
		end;
	when user_not_reg_exception then
		begin
		OP_OP_CODE:=-2;
		 OPEN OP_SEL_RESULT FOR
		 select '用户未注册' from dual;
		end;
	when user_lock_exception then
		begin
		OP_OP_CODE:=-3;
		 OPEN OP_SEL_RESULT FOR
		 select '用户被锁定' from dual;
		end;
	when no_data_found then
	  begin
		begin
		OP_OP_CODE:=-4;
		 OPEN OP_SEL_RESULT FOR
		 select '没有找到任何数据' from dual;
		end;
	end;
	when others then
		begin
		OP_OP_CODE:=-5;
		 OPEN OP_SEL_RESULT FOR
		 select '其他错误' from dual;
		end;

END;


PROCEDURE QUERY_FELLOW(
	IP_AREACODE IN VARCHAR2,
	IP_USER_ID IN COMMON_USER.LOGIN_ID%TYPE,

	OP_SEL_RESULT OUT SYS_REFCURSOR,
	OP_OP_CODE OUT NUMBER
)
IS
	user_not_exist_exception exception;
	user_not_reg_exception exception;
	user_lock_exception exception;
	t_user_count number(1,0);
	t_reg_status number(1,0);
	t_lock_status number(1,0);
	V_CUR_PAGE NUMBER;

BEGIN
	--PERMISSION CHECK BEGIN
	select count(*) into t_user_count from common_user where login_id = IP_USER_ID;
		  
		if t_user_count = 0 then
			raise user_not_exist_exception;
		end if;
		
		--user reg_status
		select REGSTATUS into t_reg_status from common_user  where login_id = IP_USER_ID;
		if t_reg_status <> 0 then
			raise user_not_reg_exception;
		end if;
		
		--user lock stauts
		select STATUS into t_lock_status from common_user where login_id = IP_USER_ID;
		if t_lock_status <> 0 then
			raise user_lock_exception;
		end if;
	
	-- V_CUR_PAGE:=(IP_PAGE_INDEX - 1) * IP_PAGE_SIZE;
	
	--PERMISSION CHECK END
	
	
	   OPEN OP_SEL_RESULT FOR
  
   
	  
		 SELECT * FROM COMMON_USER LEFT JOIN common_user_profile ON COMMON_USER.LOGIN_ID=common_user_profile.LOGIN_ID
WHERE COMMON_USER.REGSTATUS = 0 AND STATUS = 0 AND ( COMMON_USER.IDNUMBER LIKE IP_AREACODE||'%'  )
ORDER BY common_user.login_id;
		
			 
			 
	
		OP_OP_CODE:=1;
	
exception 
	
	when user_not_exist_exception then
		begin
		OP_OP_CODE:=-1;
		 OPEN OP_SEL_RESULT FOR
		 select '用户不存在' from dual;
		end;
	when user_not_reg_exception then
		begin
		OP_OP_CODE:=-2;
		 OPEN OP_SEL_RESULT FOR
		 select '用户未注册' from dual;
		end;
	when user_lock_exception then
		begin
		OP_OP_CODE:=-3;
		 OPEN OP_SEL_RESULT FOR
		 select '用户被锁定' from dual;
		end;
	when no_data_found then
	  begin
		begin
		OP_OP_CODE:=-4;
		 OPEN OP_SEL_RESULT FOR
		 select '没有找到任何数据' from dual;
		end;
	end;
	when others then
		begin
		OP_OP_CODE:=-5;
		 OPEN OP_SEL_RESULT FOR
		 select '其他错误' from dual;
		end;

END;



END COMMON_USER_tapi;

/
--------------------------------------------------------
--  DDL for Package Body DBMS_REPCAT_AUTH
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."DBMS_REPCAT_AUTH" wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
b
ba5 3a0
WEr0nOgRMSPBS3Z7Kvjx5JCUt2owg5WnTCCDfI5Av1UPOFy3ytP8lZ8t3hEfG60CTfSQMcvV
6ivyNKey557uUQmq5H5JbD4u2nCU8C8sxsa7x7zmdjj+nij7sk14NSnX4GLHDewbAlnflaQV
5Ip0a4vV4HdElsmpesU60A7ZRG8v4fOFSRFfWNoVil6uEiKYBLiqWripX8GpJaZ8UshyxIOj
3EV/homo0wcdcBB50gZ8bonh0GB5pN1QSW8ltNLN2ps5qHg4TFDnWgG7up3N8kaIB0jtO+rR
OP839Jnm3sPBXdL8EIaW3GOR7ycVj6toVCHpkKRN/WnLPYPi/XGYL71P09LHNjbMf+HU9z+W
ttKW9ohPDLdUXmufaLawN9vr5XOAgXkPX9PgtMFLHhe8jXO5u0o3rjZ87bqbdX97dwK3zxUy
OkWEQPSP30tF7ju3s8C+dWlmC1W3i3GtyWbzGK2Eurr+TuoTsQS0Dt/syQBYtpARlGmMcJ/Q
uZHG0WvcncL9qX/vNbNCWwB6eljzuQfMpuir8Y8vRTLYSlLNbup7L7i0RH8E69URqExlq/ko
CrPr/P+gWYZqqKbq0vWo8JEolfewBUbS3Tu7sQKjcYnE5Mb8PMR/fVNBoOXYkAMs3eudRCE1
YAM+sULch667d2YxFf7vvKfyn066LtD/6OlO0EWc6368k1axWwIxZjIKp8Wuno28ytJgAT8N
j5LHQVUcVKXxVfHM7P8oicVqILtVxXIrgOk8iVWdqwrPp0MDBvmkyJvfct+wRz2bw6Mum72v
bKVdOosnO6+VVrq8mcPRw1KcY0mRSRP16HIg6fdySN8Ce94HnJ2LA9Squbok3/mN0v1H0lLO
XPFJRbPFqmI2+F8/KVORKCsXMw4BHLV0Zh+Z9At//KrOmWxKssU=


/
--------------------------------------------------------
--  DDL for Package Body JSON_AC
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_AC" as
  procedure object_remove(p_self in out nocopy json, pair_name varchar2) as
  begin p_self.remove(pair_name); end;
  procedure object_put(p_self in out nocopy json, pair_name varchar2, pair_value json_value, position pls_integer default null) as
  begin p_self.put(pair_name, pair_value, position); end;
  procedure object_put(p_self in out nocopy json, pair_name varchar2, pair_value varchar2, position pls_integer default null) as
  begin p_self.put(pair_name, pair_value, position); end;
  procedure object_put(p_self in out nocopy json, pair_name varchar2, pair_value number, position pls_integer default null) as
  begin p_self.put(pair_name, pair_value, position); end;
  procedure object_put(p_self in out nocopy json, pair_name varchar2, pair_value boolean, position pls_integer default null) as
  begin p_self.put(pair_name, pair_value, position); end;
  procedure object_check_duplicate(p_self in out nocopy json, v_set boolean) as
  begin p_self.check_duplicate(v_set); end;
  procedure object_remove_duplicates(p_self in out nocopy json) as
  begin p_self.remove_duplicates; end;

  procedure object_put(p_self in out nocopy json, pair_name varchar2, pair_value json, position pls_integer default null) as
  begin p_self.put(pair_name, pair_value, position); end;
  procedure object_put(p_self in out nocopy json, pair_name varchar2, pair_value json_list, position pls_integer default null) as
  begin p_self.put(pair_name, pair_value, position); end;

  function object_count(p_self in json) return number as
  begin return p_self.count; end;
  function object_get(p_self in json, pair_name varchar2) return json_value as
  begin return p_self.get(pair_name); end;
  function object_get(p_self in json, position pls_integer) return json_value as
  begin return p_self.get(position); end;
  function object_index_of(p_self in json, pair_name varchar2) return number as
  begin return p_self.index_of(pair_name); end;
  function object_exist(p_self in json, pair_name varchar2) return boolean as
  begin return p_self.exist(pair_name); end;

  function object_to_char(p_self in json, spaces boolean default true, chars_per_line number default 0) return varchar2 as
  begin return p_self.to_char(spaces, chars_per_line); end;
  procedure object_to_clob(p_self in json, buf in out nocopy clob, spaces boolean default false, chars_per_line number default 0, erase_clob boolean default true) as
  begin p_self.to_clob(buf, spaces, chars_per_line, erase_clob); end;
  procedure object_print(p_self in json, spaces boolean default true, chars_per_line number default 8192, jsonp varchar2 default null) as
  begin p_self.print(spaces, chars_per_line, jsonp); end;
  procedure object_htp(p_self in json, spaces boolean default false, chars_per_line number default 0, jsonp varchar2 default null) as
  begin p_self.htp(spaces, chars_per_line, jsonp); end;

  function object_to_json_value(p_self in json) return json_value as
  begin return p_self.to_json_value; end;
  function object_path(p_self in json, json_path varchar2, base number default 1) return json_value as
  begin return p_self.path(json_path, base); end;

  procedure object_path_put(p_self in out nocopy json, json_path varchar2, elem json_value, base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure object_path_put(p_self in out nocopy json, json_path varchar2, elem varchar2  , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure object_path_put(p_self in out nocopy json, json_path varchar2, elem number    , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure object_path_put(p_self in out nocopy json, json_path varchar2, elem boolean   , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure object_path_put(p_self in out nocopy json, json_path varchar2, elem json_list , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure object_path_put(p_self in out nocopy json, json_path varchar2, elem json      , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;

  procedure object_path_remove(p_self in out nocopy json, json_path varchar2, base number default 1) as
  begin p_self.path_remove(json_path, base); end;

  function object_get_values(p_self in json) return json_list as
  begin return p_self.get_values; end;
  function object_get_keys(p_self in json) return json_list as
  begin return p_self.get_keys; end;

  --json_list type
  procedure array_append(p_self in out nocopy json_list, elem json_value, position pls_integer default null) as
  begin p_self.append(elem, position); end;
  procedure array_append(p_self in out nocopy json_list, elem varchar2, position pls_integer default null) as
  begin p_self.append(elem, position); end;
  procedure array_append(p_self in out nocopy json_list, elem number, position pls_integer default null) as
  begin p_self.append(elem, position); end;
  procedure array_append(p_self in out nocopy json_list, elem boolean, position pls_integer default null) as
  begin p_self.append(elem, position); end;
  procedure array_append(p_self in out nocopy json_list, elem json_list, position pls_integer default null) as
  begin p_self.append(elem, position); end;

  procedure array_replace(p_self in out nocopy json_list, position pls_integer, elem json_value) as
  begin p_self.replace(position, elem); end;
  procedure array_replace(p_self in out nocopy json_list, position pls_integer, elem varchar2) as
  begin p_self.replace(position, elem); end;
  procedure array_replace(p_self in out nocopy json_list, position pls_integer, elem number) as
  begin p_self.replace(position, elem); end;
  procedure array_replace(p_self in out nocopy json_list, position pls_integer, elem boolean) as
  begin p_self.replace(position, elem); end;
  procedure array_replace(p_self in out nocopy json_list, position pls_integer, elem json_list) as
  begin p_self.replace(position, elem); end;

  function array_count(p_self in json_list) return number as
  begin return p_self.count; end;
  procedure array_remove(p_self in out nocopy json_list, position pls_integer) as
  begin p_self.remove(position); end;
  procedure array_remove_first(p_self in out nocopy json_list) as
  begin p_self.remove_first; end;
  procedure array_remove_last(p_self in out nocopy json_list) as
  begin p_self.remove_last; end;
  function array_get(p_self in json_list, position pls_integer) return json_value as
  begin return p_self.get(position); end;
  function array_head(p_self in json_list) return json_value as
  begin return p_self.head; end;
  function array_last(p_self in json_list) return json_value as
  begin return p_self.last; end;
  function array_tail(p_self in json_list) return json_list as
  begin return p_self.tail; end;

  function array_to_char(p_self in json_list, spaces boolean default true, chars_per_line number default 0) return varchar2 as
  begin return p_self.to_char(spaces, chars_per_line); end;
  procedure array_to_clob(p_self in json_list, buf in out nocopy clob, spaces boolean default false, chars_per_line number default 0, erase_clob boolean default true) as
  begin p_self.to_clob(buf, spaces, chars_per_line, erase_clob); end;
  procedure array_print(p_self in json_list, spaces boolean default true, chars_per_line number default 8192, jsonp varchar2 default null) as
  begin p_self.print(spaces, chars_per_line, jsonp); end;
  procedure array_htp(p_self in json_list, spaces boolean default false, chars_per_line number default 0, jsonp varchar2 default null) as
  begin p_self.htp(spaces, chars_per_line, jsonp); end;

  function array_path(p_self in json_list, json_path varchar2, base number default 1) return json_value as
  begin return p_self.path(json_path, base); end;
  procedure array_path_put(p_self in out nocopy json_list, json_path varchar2, elem json_value, base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure array_path_put(p_self in out nocopy json_list, json_path varchar2, elem varchar2  , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure array_path_put(p_self in out nocopy json_list, json_path varchar2, elem number    , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure array_path_put(p_self in out nocopy json_list, json_path varchar2, elem boolean   , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;
  procedure array_path_put(p_self in out nocopy json_list, json_path varchar2, elem json_list , base number default 1) as
  begin p_self.path_put(json_path, elem, base); end;

  procedure array_path_remove(p_self in out nocopy json_list, json_path varchar2, base number default 1) as
  begin p_self.path_remove(json_path, base); end;

  function array_to_json_value(p_self in json_list) return json_value as
  begin return p_self.to_json_value; end;

  --json_value


  function jv_get_type(p_self in json_value) return varchar2 as
  begin return p_self.get_type; end;
  function jv_get_string(p_self in json_value, max_byte_size number default null, max_char_size number default null) return varchar2 as
  begin return p_self.get_string(max_byte_size, max_char_size); end;
  procedure jv_get_string(p_self in json_value, buf in out nocopy clob) as
  begin p_self.get_string(buf); end;
  function jv_get_number(p_self in json_value) return number as
  begin return p_self.get_number; end;
  function jv_get_bool(p_self in json_value) return boolean as
  begin return p_self.get_bool; end;
  function jv_get_null(p_self in json_value) return varchar2 as
  begin return p_self.get_null; end;

  function jv_is_object(p_self in json_value) return boolean as
  begin return p_self.is_object; end;
  function jv_is_array(p_self in json_value) return boolean as
  begin return p_self.is_array; end;
  function jv_is_string(p_self in json_value) return boolean as
  begin return p_self.is_string; end;
  function jv_is_number(p_self in json_value) return boolean as
  begin return p_self.is_number; end;
  function jv_is_bool(p_self in json_value) return boolean as
  begin return p_self.is_bool; end;
  function jv_is_null(p_self in json_value) return boolean as
  begin return p_self.is_null; end;

  function jv_to_char(p_self in json_value, spaces boolean default true, chars_per_line number default 0) return varchar2 as
  begin return p_self.to_char(spaces, chars_per_line); end;
  procedure jv_to_clob(p_self in json_value, buf in out nocopy clob, spaces boolean default false, chars_per_line number default 0, erase_clob boolean default true) as
  begin p_self.to_clob(buf, spaces, chars_per_line, erase_clob); end;
  procedure jv_print(p_self in json_value, spaces boolean default true, chars_per_line number default 8192, jsonp varchar2 default null) as
  begin p_self.print(spaces, chars_per_line, jsonp); end;
  procedure jv_htp(p_self in json_value, spaces boolean default false, chars_per_line number default 0, jsonp varchar2 default null) as
  begin p_self.htp(spaces, chars_per_line, jsonp); end;

  function jv_value_of(p_self in json_value, max_byte_size number default null, max_char_size number default null) return varchar2 as
  begin return p_self.value_of(max_byte_size, max_char_size); end;

end json_ac;

/
--------------------------------------------------------
--  DDL for Package Body JSON_DYN
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_DYN" as
/*
  -- 11gR2
  function executeList(stmt in out sys_refcursor) return json_list as
    l_cur number;
  begin
    l_cur := dbms_sql.to_cursor_number(stmt);
    return json_dyn.executeList(null, null, l_cur);
  end;

  -- 11gR2
  function executeObject(stmt in out sys_refcursor) return json as
    l_cur number;
  begin
    l_cur := dbms_sql.to_cursor_number(stmt);
    return json_dyn.executeObject(null, null, l_cur);
  end;
*/

  procedure bind_json(l_cur number, bindvar json) as
    keylist json_list := bindvar.get_keys();
  begin
    for i in 1 .. keylist.count loop
      if(bindvar.get(i).get_type = 'number') then
        dbms_sql.bind_variable(l_cur, ':'||keylist.get(i).get_string, bindvar.get(i).get_number);
      elsif(bindvar.get(i).get_type = 'array') then
        declare
          v_bind dbms_sql.varchar2_table;
          v_arr  json_list := json_list(bindvar.get(i));
        begin
          for j in 1 .. v_arr.count loop
            v_bind(j) := v_arr.get(j).value_of;
          end loop;
          dbms_sql.bind_array(l_cur, ':'||keylist.get(i).get_string, v_bind);
        end;
      else
        dbms_sql.bind_variable(l_cur, ':'||keylist.get(i).get_string, bindvar.get(i).value_of());
      end if;
    end loop;
  end bind_json;

  /* list with objects */
  function executeList(stmt varchar2, bindvar json, cur_num number) return json_list as
    l_cur number;
    l_dtbl dbms_sql.desc_tab;
    l_cnt number;
    l_status number;
    l_val varchar2(4000);
    outer_list json_list := json_list();
    inner_obj json;
    conv number;
    read_date date;
    read_clob clob;
    read_blob blob;
    col_type number;
  begin
    if(cur_num is not null) then
      l_cur := cur_num;
    else
      l_cur := dbms_sql.open_cursor;
      dbms_sql.parse(l_cur, stmt, dbms_sql.native);
      if(bindvar is not null) then bind_json(l_cur, bindvar); end if;
    end if;
    dbms_sql.describe_columns(l_cur, l_cnt, l_dtbl);
    for i in 1..l_cnt loop
      col_type := l_dtbl(i).col_type;
      --dbms_output.put_line(col_type);
      if(col_type = 12) then
        dbms_sql.define_column(l_cur,i,read_date);
      elsif(col_type = 112) then
        dbms_sql.define_column(l_cur,i,read_clob);
      elsif(col_type = 113) then
        dbms_sql.define_column(l_cur,i,read_blob);
      elsif(col_type in (1,2,96)) then
        dbms_sql.define_column(l_cur,i,l_val,4000);
      end if;
    end loop;

    if(cur_num is null) then l_status := dbms_sql.execute(l_cur); end if;

    --loop through rows
    while ( dbms_sql.fetch_rows(l_cur) > 0 ) loop
      inner_obj := json(); --init for each row
      --loop through columns
      for i in 1..l_cnt loop
        case true
        --handling string types
        when l_dtbl(i).col_type in (1,96) then -- varchar2
          dbms_sql.column_value(l_cur,i,l_val);
          if(l_val is null) then
            if(null_as_empty_string) then
              inner_obj.put(l_dtbl(i).col_name, ''); --treatet as emptystring?
            else
              inner_obj.put(l_dtbl(i).col_name, json_value.makenull); --null
            end if;
          else
            inner_obj.put(l_dtbl(i).col_name, json_value(l_val)); --null
          end if;
          --dbms_output.put_line(l_dtbl(i).col_name||' --> '||l_val||'varchar2' ||l_dtbl(i).col_type);
        --handling number types
        when l_dtbl(i).col_type = 2 then -- number
          dbms_sql.column_value(l_cur,i,l_val);
          conv := l_val;
          inner_obj.put(l_dtbl(i).col_name, conv);
          -- dbms_output.put_line(l_dtbl(i).col_name||' --> '||l_val||'number ' ||l_dtbl(i).col_type);
        when l_dtbl(i).col_type = 12 then -- date
          if(include_dates) then
            dbms_sql.column_value(l_cur,i,read_date);
            inner_obj.put(l_dtbl(i).col_name, json_ext.to_json_value(read_date));
          end if;
          --dbms_output.put_line(l_dtbl(i).col_name||' --> '||l_val||'date ' ||l_dtbl(i).col_type);
        when l_dtbl(i).col_type = 112 then --clob
          if(include_clobs) then
            dbms_sql.column_value(l_cur,i,read_clob);
            inner_obj.put(l_dtbl(i).col_name, json_value(read_clob));
          end if;
        when l_dtbl(i).col_type = 113 then --blob
          if(include_blobs) then
            dbms_sql.column_value(l_cur,i,read_blob);
            if(dbms_lob.getlength(read_blob) > 0) then
              inner_obj.put(l_dtbl(i).col_name, json_ext.encode(read_blob));
            else
              inner_obj.put(l_dtbl(i).col_name, json_value.makenull);
            end if;
          end if;

        else null; --discard other types
        end case;
      end loop;
      outer_list.append(inner_obj.to_json_value);
    end loop;
    dbms_sql.close_cursor(l_cur);
    return outer_list;
  end executeList;

  /* object with lists */
  function executeObject(stmt varchar2, bindvar json, cur_num number) return json as
    l_cur number;
    l_dtbl dbms_sql.desc_tab;
    l_cnt number;
    l_status number;
    l_val varchar2(4000);
    inner_list_names json_list := json_list();
    inner_list_data json_list := json_list();
    data_list json_list;
    outer_obj json := json();
    conv number;
    read_date date;
    read_clob clob;
    read_blob blob;
    col_type number;
  begin
    if(cur_num is not null) then
      l_cur := cur_num;
    else
      l_cur := dbms_sql.open_cursor;
      dbms_sql.parse(l_cur, stmt, dbms_sql.native);
      if(bindvar is not null) then bind_json(l_cur, bindvar); end if;
    end if;
    dbms_sql.describe_columns(l_cur, l_cnt, l_dtbl);
    for i in 1..l_cnt loop
      col_type := l_dtbl(i).col_type;
      if(col_type = 12) then
        dbms_sql.define_column(l_cur,i,read_date);
      elsif(col_type = 112) then
        dbms_sql.define_column(l_cur,i,read_clob);
      elsif(col_type = 113) then
        dbms_sql.define_column(l_cur,i,read_blob);
      elsif(col_type in (1,2,96)) then
        dbms_sql.define_column(l_cur,i,l_val,4000);
      end if;
    end loop;
    if(cur_num is null) then l_status := dbms_sql.execute(l_cur); end if;

    --build up name_list
    for i in 1..l_cnt loop
      case l_dtbl(i).col_type
        when 1 then inner_list_names.append(l_dtbl(i).col_name);
        when 96 then inner_list_names.append(l_dtbl(i).col_name);
        when 2 then inner_list_names.append(l_dtbl(i).col_name);
        when 12 then if(include_dates) then inner_list_names.append(l_dtbl(i).col_name); end if;
        when 112 then if(include_clobs) then inner_list_names.append(l_dtbl(i).col_name); end if;
        when 113 then if(include_blobs) then inner_list_names.append(l_dtbl(i).col_name); end if;
        else null;
      end case;
    end loop;

    --loop through rows
    while ( dbms_sql.fetch_rows(l_cur) > 0 ) loop
      data_list := json_list();
      --loop through columns
      for i in 1..l_cnt loop
        case true
        --handling string types
        when l_dtbl(i).col_type in (1,96) then -- varchar2
          dbms_sql.column_value(l_cur,i,l_val);
          if(l_val is null) then
            if(null_as_empty_string) then
              data_list.append(''); --treatet as emptystring?
            else
              data_list.append(json_value.makenull); --null
            end if;
          else
            data_list.append(json_value(l_val)); --null
          end if;
          --dbms_output.put_line(l_dtbl(i).col_name||' --> '||l_val||'varchar2' ||l_dtbl(i).col_type);
        --handling number types
        when l_dtbl(i).col_type = 2 then -- number
          dbms_sql.column_value(l_cur,i,l_val);
          conv := l_val;
          data_list.append(conv);
          -- dbms_output.put_line(l_dtbl(i).col_name||' --> '||l_val||'number ' ||l_dtbl(i).col_type);
        when l_dtbl(i).col_type = 12 then -- date
          if(include_dates) then
            dbms_sql.column_value(l_cur,i,read_date);
            data_list.append(json_ext.to_json_value(read_date));
          end if;
          --dbms_output.put_line(l_dtbl(i).col_name||' --> '||l_val||'date ' ||l_dtbl(i).col_type);
        when l_dtbl(i).col_type = 112 then --clob
          if(include_clobs) then
            dbms_sql.column_value(l_cur,i,read_clob);
            data_list.append(json_value(read_clob));
          end if;
        when l_dtbl(i).col_type = 113 then --blob
          if(include_blobs) then
            dbms_sql.column_value(l_cur,i,read_blob);
            if(dbms_lob.getlength(read_blob) > 0) then
              data_list.append(json_ext.encode(read_blob));
            else
              data_list.append(json_value.makenull);
            end if;
          end if;
        else null; --discard other types
        end case;
      end loop;
      inner_list_data.append(data_list);
    end loop;

    outer_obj.put('names', inner_list_names.to_json_value);
    outer_obj.put('data', inner_list_data.to_json_value);
    dbms_sql.close_cursor(l_cur);
    return outer_obj;
  end executeObject;

end json_dyn;

/
--------------------------------------------------------
--  DDL for Package Body JSON_EXT
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_EXT" as
  scanner_exception exception;
  pragma exception_init(scanner_exception, -20100);
  parser_exception exception;
  pragma exception_init(parser_exception, -20101);
  jext_exception exception;
  pragma exception_init(jext_exception, -20110);

  --extra function checks if number has no fraction
  function is_integer(v json_value) return boolean as
    myint number(38); --the oracle way to specify an integer
  begin
    if(v.is_number) then
      myint := v.get_number;
      return (myint = v.get_number); --no rounding errors?
    else
      return false;
    end if;
  end;

  --extension enables json to store dates without comprimising the implementation
  function to_json_value(d date) return json_value as
  begin
    return json_value(to_char(d, format_string));
  end;

  --notice that a date type in json is also a varchar2
  function is_date(v json_value) return boolean as
    temp date;
  begin
    temp := json_ext.to_date2(v);
    return true;
  exception
    when others then
      return false;
  end;

  --convertion is needed to extract dates
  function to_date2(v json_value) return date as
  begin
    if(v.is_string) then
      return to_date(v.get_string, format_string);
    else
      raise_application_error(-20110, 'Anydata did not contain a date-value');
    end if;
  exception
    when others then
      raise_application_error(-20110, 'Anydata did not contain a date on the format: '||format_string);
  end;

  --Json Path parser
  function parsePath(json_path varchar2, base number default 1) return json_list as
    build_path varchar2(32767) := '[';
    buf varchar2(4);
    endstring varchar2(1);
    indx number := 1;
    ret json_list;

    procedure next_char as
    begin
      if(indx <= length(json_path)) then
        buf := substr(json_path, indx, 1);
        indx := indx + 1;
      else
        buf := null;
      end if;
    end;
    --skip ws
    procedure skipws as begin while(buf in (chr(9),chr(10),chr(13),' ')) loop next_char; end loop; end;

  begin
    next_char();
    while(buf is not null) loop
      if(buf = '.') then
        next_char();
        if(buf is null) then raise_application_error(-20110, 'JSON Path parse error: . is not a valid json_path end'); end if;
        if(not regexp_like(buf, '^[[:alnum:]\_ ]+', 'c') ) then
          raise_application_error(-20110, 'JSON Path parse error: alpha-numeric character or space expected at position '||indx);
        end if;

        if(build_path != '[') then build_path := build_path || ','; end if;
        build_path := build_path || '"';
        while(regexp_like(buf, '^[[:alnum:]\_ ]+', 'c') ) loop
          build_path := build_path || buf;
          next_char();
        end loop;
        build_path := build_path || '"';
      elsif(buf = '[') then
        next_char();
        skipws();
        if(buf is null) then raise_application_error(-20110, 'JSON Path parse error: [ is not a valid json_path end'); end if;
        if(buf in ('1','2','3','4','5','6','7','8','9') or (buf = '0' and base = 0)) then
          if(build_path != '[') then build_path := build_path || ','; end if;
          while(buf in ('0','1','2','3','4','5','6','7','8','9')) loop
            build_path := build_path || buf;
            next_char();
          end loop;
        elsif (regexp_like(buf, '^(\"|\'')', 'c')) then
          endstring := buf;
          if(build_path != '[') then build_path := build_path || ','; end if;
          build_path := build_path || '"';
          next_char();
          if(buf is null) then raise_application_error(-20110, 'JSON Path parse error: premature json_path end'); end if;
          while(buf != endstring) loop
            build_path := build_path || buf;
            next_char();
            if(buf is null) then raise_application_error(-20110, 'JSON Path parse error: premature json_path end'); end if;
            if(buf = '\') then
              next_char();
              build_path := build_path || '\' || buf;
              next_char();
            end if;
          end loop;
          build_path := build_path || '"';
          next_char();
        else
          raise_application_error(-20110, 'JSON Path parse error: expected a string or an positive integer at '||indx);
        end if;
        skipws();
        if(buf is null) then raise_application_error(-20110, 'JSON Path parse error: premature json_path end'); end if;
        if(buf != ']') then raise_application_error(-20110, 'JSON Path parse error: no array ending found. found: '|| buf); end if;
        next_char();
        skipws();
      elsif(build_path = '[') then
        if(not regexp_like(buf, '^[[:alnum:]\_ ]+', 'c') ) then
          raise_application_error(-20110, 'JSON Path parse error: alpha-numeric character or space expected at position '||indx);
        end if;
        build_path := build_path || '"';
        while(regexp_like(buf, '^[[:alnum:]\_ ]+', 'c') ) loop
          build_path := build_path || buf;
          next_char();
        end loop;
        build_path := build_path || '"';
      else
        raise_application_error(-20110, 'JSON Path parse error: expected . or [ found '|| buf || ' at position '|| indx);
      end if;

    end loop;

    build_path := build_path || ']';
    build_path := replace(replace(replace(replace(replace(build_path, chr(9), '\t'), chr(10), '\n'), chr(13), '\f'), chr(8), '\b'), chr(14), '\r');

    ret := json_list(build_path);
    if(base != 1) then
      --fix base 0 to base 1
      declare
        elem json_value;
      begin
        for i in 1 .. ret.count loop
          elem := ret.get(i);
          if(elem.is_number) then
            ret.replace(i,elem.get_number()+1);
          end if;
        end loop;
      end;
    end if;

    return ret;
  end parsePath;

  --JSON Path getters
  function get_json_value(obj json, v_path varchar2, base number default 1) return json_value as
    path json_list;
    ret json_value;
    o json; l json_list;
  begin
    path := parsePath(v_path, base);
    ret := obj.to_json_value;
    if(path.count = 0) then return ret; end if;

    for i in 1 .. path.count loop
      if(path.get(i).is_string()) then
        --string fetch only on json
        o := json(ret);
        ret := o.get(path.get(i).get_string());
      else
        --number fetch on json and json_list
        if(ret.is_array()) then
          l := json_list(ret);
          ret := l.get(path.get(i).get_number());
        else
          o := json(ret);
          l := o.get_values();
          ret := l.get(path.get(i).get_number());
        end if;
      end if;
    end loop;

    return ret;
  exception
    when scanner_exception then raise;
    when parser_exception then raise;
    when jext_exception then raise;
    when others then return null;
  end get_json_value;

  --JSON Path getters
  function get_string(obj json, path varchar2, base number default 1) return varchar2 as
    temp json_value;
  begin
    temp := get_json_value(obj, path, base);
    if(temp is null or not temp.is_string) then
      return null;
    else
      return temp.get_string;
    end if;
  end;

  function get_number(obj json, path varchar2, base number default 1) return number as
    temp json_value;
  begin
    temp := get_json_value(obj, path, base);
    if(temp is null or not temp.is_number) then
      return null;
    else
      return temp.get_number;
    end if;
  end;

  function get_json(obj json, path varchar2, base number default 1) return json as
    temp json_value;
  begin
    temp := get_json_value(obj, path, base);
    if(temp is null or not temp.is_object) then
      return null;
    else
      return json(temp);
    end if;
  end;

  function get_json_list(obj json, path varchar2, base number default 1) return json_list as
    temp json_value;
  begin
    temp := get_json_value(obj, path, base);
    if(temp is null or not temp.is_array) then
      return null;
    else
      return json_list(temp);
    end if;
  end;

  function get_bool(obj json, path varchar2, base number default 1) return boolean as
    temp json_value;
  begin
    temp := get_json_value(obj, path, base);
    if(temp is null or not temp.is_bool) then
      return null;
    else
      return temp.get_bool;
    end if;
  end;

  function get_date(obj json, path varchar2, base number default 1) return date as
    temp json_value;
  begin
    temp := get_json_value(obj, path, base);
    if(temp is null or not is_date(temp)) then
      return null;
    else
      return json_ext.to_date2(temp);
    end if;
  end;

  /* JSON Path putter internal function */
  procedure put_internal(obj in out nocopy json, v_path varchar2, elem json_value, base number) as
    val json_value := elem;
    path json_list;
    backreference json_list := json_list();

    keyval json_value; keynum number; keystring varchar2(4000);
    temp json_value := obj.to_json_value;
    obj_temp  json;
    list_temp json_list;
    inserter json_value;
  begin
    path := json_ext.parsePath(v_path, base);
    if(path.count = 0) then raise_application_error(-20110, 'JSON_EXT put error: cannot put with empty string.'); end if;

    --build backreference
    for i in 1 .. path.count loop
      --backreference.print(false);
      keyval := path.get(i);
      if (keyval.is_number()) then
        --nummer index
        keynum := keyval.get_number();
        if((not temp.is_object()) and (not temp.is_array())) then
          if(val is null) then return; end if;
          backreference.remove_last;
          temp := json_list().to_json_value();
          backreference.append(temp);
        end if;

        if(temp.is_object()) then
          obj_temp := json(temp);
          if(obj_temp.count < keynum) then
            if(val is null) then return; end if;
            raise_application_error(-20110, 'JSON_EXT put error: access object with to few members.');
          end if;
          temp := obj_temp.get(keynum);
        else
          list_temp := json_list(temp);
          if(list_temp.count < keynum) then
            if(val is null) then return; end if;
            --raise error or quit if val is null
            for i in list_temp.count+1 .. keynum loop
              list_temp.append(json_value.makenull);
            end loop;
            backreference.remove_last;
            backreference.append(list_temp);
          end if;

          temp := list_temp.get(keynum);
        end if;
      else
        --streng index
        keystring := keyval.get_string();
        if(not temp.is_object()) then
          --backreference.print;
          if(val is null) then return; end if;
          backreference.remove_last;
          temp := json().to_json_value();
          backreference.append(temp);
          --raise_application_error(-20110, 'JSON_ext put error: trying to access a non object with a string.');
        end if;
        obj_temp := json(temp);
        temp := obj_temp.get(keystring);
      end if;

      if(temp is null) then
        if(val is null) then return; end if;
        --what to expect?
        keyval := path.get(i+1);
        if(keyval is not null and keyval.is_number()) then
          temp := json_list().to_json_value;
        else
          temp := json().to_json_value;
        end if;
      end if;
      backreference.append(temp);
    end loop;

  --  backreference.print(false);
  --  path.print(false);

    --use backreference and path together
    inserter := val;
    for i in reverse 1 .. backreference.count loop
  --    inserter.print(false);
      if( i = 1 ) then
        keyval := path.get(1);
        if(keyval.is_string()) then
          keystring := keyval.get_string();
        else
          keynum := keyval.get_number();
          declare
            t1 json_value := obj.get(keynum);
          begin
            keystring := t1.mapname;
          end;
        end if;
        if(inserter is null) then obj.remove(keystring); else obj.put(keystring, inserter); end if;
      else
        temp := backreference.get(i-1);
        if(temp.is_object()) then
          keyval := path.get(i);
          obj_temp := json(temp);
          if(keyval.is_string()) then
            keystring := keyval.get_string();
          else
            keynum := keyval.get_number();
            declare
              t1 json_value := obj_temp.get(keynum);
            begin
              keystring := t1.mapname;
            end;
          end if;
          if(inserter is null) then
            obj_temp.remove(keystring);
            if(obj_temp.count > 0) then inserter := obj_temp.to_json_value; end if;
          else
            obj_temp.put(keystring, inserter);
            inserter := obj_temp.to_json_value;
          end if;
        else
          --array only number
          keynum := path.get(i).get_number();
          list_temp := json_list(temp);
          list_temp.remove(keynum);
          if(not inserter is null) then
            list_temp.append(inserter, keynum);
            inserter := list_temp.to_json_value;
          else
            if(list_temp.count > 0) then inserter := list_temp.to_json_value; end if;
          end if;
        end if;
      end if;

    end loop;

  end put_internal;

  /* JSON Path putters */
  procedure put(obj in out nocopy json, path varchar2, elem varchar2, base number default 1) as
  begin
    put_internal(obj, path, json_value(elem), base);
  end;

  procedure put(obj in out nocopy json, path varchar2, elem number, base number default 1) as
  begin
    if(elem is null) then raise_application_error(-20110, 'Cannot put null-value'); end if;
    put_internal(obj, path, json_value(elem), base);
  end;

  procedure put(obj in out nocopy json, path varchar2, elem json, base number default 1) as
  begin
    if(elem is null) then raise_application_error(-20110, 'Cannot put null-value'); end if;
    put_internal(obj, path, elem.to_json_value, base);
  end;

  procedure put(obj in out nocopy json, path varchar2, elem json_list, base number default 1) as
  begin
    if(elem is null) then raise_application_error(-20110, 'Cannot put null-value'); end if;
    put_internal(obj, path, elem.to_json_value, base);
  end;

  procedure put(obj in out nocopy json, path varchar2, elem boolean, base number default 1) as
  begin
    if(elem is null) then raise_application_error(-20110, 'Cannot put null-value'); end if;
    put_internal(obj, path, json_value(elem), base);
  end;

  procedure put(obj in out nocopy json, path varchar2, elem json_value, base number default 1) as
  begin
    if(elem is null) then raise_application_error(-20110, 'Cannot put null-value'); end if;
    put_internal(obj, path, elem, base);
  end;

  procedure put(obj in out nocopy json, path varchar2, elem date, base number default 1) as
  begin
    if(elem is null) then raise_application_error(-20110, 'Cannot put null-value'); end if;
    put_internal(obj, path, json_ext.to_json_value(elem), base);
  end;

  procedure remove(obj in out nocopy json, path varchar2, base number default 1) as
  begin
    json_ext.put_internal(obj,path,null,base);
--    if(json_ext.get_json_value(obj,path) is not null) then
--    end if;
  end remove;

    --Pretty print with JSON Path
  function pp(obj json, v_path varchar2) return varchar2 as
    json_part json_value;
  begin
    json_part := json_ext.get_json_value(obj, v_path);
    if(json_part is null) then
      return '';
    else
      return json_printer.pretty_print_any(json_part); --escapes a possible internal string
    end if;
  end pp;

  procedure pp(obj json, v_path varchar2) as --using dbms_output.put_line
  begin
    dbms_output.put_line(pp(obj, v_path));
  end pp;

  -- spaces = false!
  procedure pp_htp(obj json, v_path varchar2) as --using htp.print
    json_part json_value;
  begin
    json_part := json_ext.get_json_value(obj, v_path);
    if(json_part is null) then htp.print; else
      htp.print(json_printer.pretty_print_any(json_part, false));
    end if;
  end pp_htp;

  function base64(binarydata blob) return json_list as
    obj json_list := json_list();
    c clob := empty_clob();
    benc blob;

    v_blob_offset NUMBER := 1;
    v_clob_offset NUMBER := 1;
    v_lang_context NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;
    v_warning NUMBER;
    v_amount PLS_INTEGER;
--    temp varchar2(32767);

    FUNCTION encodeBlob2Base64(pBlobIn IN BLOB) RETURN BLOB IS
      vAmount NUMBER := 45;
      vBlobEnc BLOB := empty_blob();
      vBlobEncLen NUMBER := 0;
      vBlobInLen NUMBER := 0;
      vBuffer RAW(45);
      vOffset NUMBER := 1;
    BEGIN
--      dbms_output.put_line('Start base64 encoding.');
      vBlobInLen := dbms_lob.getlength(pBlobIn);
--      dbms_output.put_line('<BlobInLength>' || vBlobInLen);
      dbms_lob.createtemporary(vBlobEnc, TRUE);
      LOOP
        IF vOffset >= vBlobInLen THEN
          EXIT;
        END IF;
        dbms_lob.read(pBlobIn, vAmount, vOffset, vBuffer);
        BEGIN
          dbms_lob.append(vBlobEnc, utl_encode.base64_encode(vBuffer));
        EXCEPTION
          WHEN OTHERS THEN
          dbms_output.put_line('<vAmount>' || vAmount || '<vOffset>' || vOffset || '<vBuffer>' || vBuffer);
          dbms_output.put_line('ERROR IN append: ' || SQLERRM);
          RAISE;
        END;
        vOffset := vOffset + vAmount;
      END LOOP;
      vBlobEncLen := dbms_lob.getlength(vBlobEnc);
--      dbms_output.put_line('<BlobEncLength>' || vBlobEncLen);
--      dbms_output.put_line('Finshed base64 encoding.');
      RETURN vBlobEnc;
    END encodeBlob2Base64;
  begin
    benc := encodeBlob2Base64(binarydata);
    dbms_lob.createtemporary(c, TRUE);
    v_amount := DBMS_LOB.GETLENGTH(benc);
    DBMS_LOB.CONVERTTOCLOB(c, benc, v_amount, v_clob_offset, v_blob_offset, 1, v_lang_context, v_warning);

    v_amount := DBMS_LOB.GETLENGTH(c);
    v_clob_offset := 1;
    --dbms_output.put_line('V amount: '||v_amount);
    while(v_clob_offset < v_amount) loop
      --dbms_output.put_line(v_offset);
      --temp := ;
      --dbms_output.put_line('size: '||length(temp));
      obj.append(dbms_lob.SUBSTR(c, 4000,v_clob_offset));
      v_clob_offset := v_clob_offset + 4000;
    end loop;
    dbms_lob.freetemporary(benc);
    dbms_lob.freetemporary(c);
  --dbms_output.put_line(obj.count);
  --dbms_output.put_line(obj.get_last().to_char);
    return obj;

  end base64;


  function base64(l json_list) return blob as
    c clob := empty_clob();
    b blob := empty_blob();
    bret blob;

    v_blob_offset NUMBER := 1;
    v_clob_offset NUMBER := 1;
    v_lang_context NUMBER := 0; --DBMS_LOB.DEFAULT_LANG_CTX;
    v_warning NUMBER;
    v_amount PLS_INTEGER;

    FUNCTION decodeBase642Blob(pBlobIn IN BLOB) RETURN BLOB IS
      vAmount NUMBER := 256;--32;
      vBlobDec BLOB := empty_blob();
      vBlobDecLen NUMBER := 0;
      vBlobInLen NUMBER := 0;
      vBuffer RAW(256);--32);
      vOffset NUMBER := 1;
    BEGIN
--      dbms_output.put_line('Start base64 decoding.');
      vBlobInLen := dbms_lob.getlength(pBlobIn);
--      dbms_output.put_line('<BlobInLength>' || vBlobInLen);
      dbms_lob.createtemporary(vBlobDec, TRUE);
      LOOP
        IF vOffset >= vBlobInLen THEN
          EXIT;
        END IF;
        dbms_lob.read(pBlobIn, vAmount, vOffset, vBuffer);
        BEGIN
          dbms_lob.append(vBlobDec, utl_encode.base64_decode(vBuffer));
        EXCEPTION
          WHEN OTHERS THEN
          dbms_output.put_line('<vAmount>' || vAmount || '<vOffset>' || vOffset || '<vBuffer>' || vBuffer);
          dbms_output.put_line('ERROR IN append: ' || SQLERRM);
          RAISE;
        END;
        vOffset := vOffset + vAmount;
      END LOOP;
      vBlobDecLen := dbms_lob.getlength(vBlobDec);
--      dbms_output.put_line('<BlobDecLength>' || vBlobDecLen);
--      dbms_output.put_line('Finshed base64 decoding.');
      RETURN vBlobDec;
    END decodeBase642Blob;
  begin
    dbms_lob.createtemporary(c, TRUE);
    for i in 1 .. l.count loop
      dbms_lob.append(c, l.get(i).get_string());
    end loop;
    v_amount := DBMS_LOB.GETLENGTH(c);
--    dbms_output.put_line('L C'||v_amount);

    dbms_lob.createtemporary(b, TRUE);
    DBMS_LOB.CONVERTTOBLOB(b, c, dbms_lob.lobmaxsize, v_clob_offset, v_blob_offset, 1, v_lang_context, v_warning);
    dbms_lob.freetemporary(c);
    v_amount := DBMS_LOB.GETLENGTH(b);
--    dbms_output.put_line('L B'||v_amount);

    bret := decodeBase642Blob(b);
    dbms_lob.freetemporary(b);
    return bret;

  end base64;

  function encode(binarydata blob) return json_value as
    obj json_value;
    c clob := empty_clob();
    benc blob;

    v_blob_offset NUMBER := 1;
    v_clob_offset NUMBER := 1;
    v_lang_context NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;
    v_warning NUMBER;
    v_amount PLS_INTEGER;
--    temp varchar2(32767);

    FUNCTION encodeBlob2Base64(pBlobIn IN BLOB) RETURN BLOB IS
      vAmount NUMBER := 45;
      vBlobEnc BLOB := empty_blob();
      vBlobEncLen NUMBER := 0;
      vBlobInLen NUMBER := 0;
      vBuffer RAW(45);
      vOffset NUMBER := 1;
    BEGIN
--      dbms_output.put_line('Start base64 encoding.');
      vBlobInLen := dbms_lob.getlength(pBlobIn);
--      dbms_output.put_line('<BlobInLength>' || vBlobInLen);
      dbms_lob.createtemporary(vBlobEnc, TRUE);
      LOOP
        IF vOffset >= vBlobInLen THEN
          EXIT;
        END IF;
        dbms_lob.read(pBlobIn, vAmount, vOffset, vBuffer);
        BEGIN
          dbms_lob.append(vBlobEnc, utl_encode.base64_encode(vBuffer));
        EXCEPTION
          WHEN OTHERS THEN
          dbms_output.put_line('<vAmount>' || vAmount || '<vOffset>' || vOffset || '<vBuffer>' || vBuffer);
          dbms_output.put_line('ERROR IN append: ' || SQLERRM);
          RAISE;
        END;
        vOffset := vOffset + vAmount;
      END LOOP;
      vBlobEncLen := dbms_lob.getlength(vBlobEnc);
--      dbms_output.put_line('<BlobEncLength>' || vBlobEncLen);
--      dbms_output.put_line('Finshed base64 encoding.');
      RETURN vBlobEnc;
    END encodeBlob2Base64;
  begin
    benc := encodeBlob2Base64(binarydata);
    dbms_lob.createtemporary(c, TRUE);
    v_amount := DBMS_LOB.GETLENGTH(benc);
    DBMS_LOB.CONVERTTOCLOB(c, benc, v_amount, v_clob_offset, v_blob_offset, 1, v_lang_context, v_warning);

    obj := json_value(c);

    dbms_lob.freetemporary(benc);
    dbms_lob.freetemporary(c);
  --dbms_output.put_line(obj.count);
  --dbms_output.put_line(obj.get_last().to_char);
    return obj;

  end encode;

  function decode(v json_value) return blob as
    c clob := empty_clob();
    b blob := empty_blob();
    bret blob;

    v_blob_offset NUMBER := 1;
    v_clob_offset NUMBER := 1;
    v_lang_context NUMBER := 0; --DBMS_LOB.DEFAULT_LANG_CTX;
    v_warning NUMBER;
    v_amount PLS_INTEGER;

    FUNCTION decodeBase642Blob(pBlobIn IN BLOB) RETURN BLOB IS
      vAmount NUMBER := 256;--32;
      vBlobDec BLOB := empty_blob();
      vBlobDecLen NUMBER := 0;
      vBlobInLen NUMBER := 0;
      vBuffer RAW(256);--32);
      vOffset NUMBER := 1;
    BEGIN
--      dbms_output.put_line('Start base64 decoding.');
      vBlobInLen := dbms_lob.getlength(pBlobIn);
--      dbms_output.put_line('<BlobInLength>' || vBlobInLen);
      dbms_lob.createtemporary(vBlobDec, TRUE);
      LOOP
        IF vOffset >= vBlobInLen THEN
          EXIT;
        END IF;
        dbms_lob.read(pBlobIn, vAmount, vOffset, vBuffer);
        BEGIN
          dbms_lob.append(vBlobDec, utl_encode.base64_decode(vBuffer));
        EXCEPTION
          WHEN OTHERS THEN
          dbms_output.put_line('<vAmount>' || vAmount || '<vOffset>' || vOffset || '<vBuffer>' || vBuffer);
          dbms_output.put_line('ERROR IN append: ' || SQLERRM);
          RAISE;
        END;
        vOffset := vOffset + vAmount;
      END LOOP;
      vBlobDecLen := dbms_lob.getlength(vBlobDec);
--      dbms_output.put_line('<BlobDecLength>' || vBlobDecLen);
--      dbms_output.put_line('Finshed base64 decoding.');
      RETURN vBlobDec;
    END decodeBase642Blob;
  begin
    dbms_lob.createtemporary(c, TRUE);
    v.get_string(c);
    v_amount := DBMS_LOB.GETLENGTH(c);
--    dbms_output.put_line('L C'||v_amount);

    dbms_lob.createtemporary(b, TRUE);
    DBMS_LOB.CONVERTTOBLOB(b, c, dbms_lob.lobmaxsize, v_clob_offset, v_blob_offset, 1, v_lang_context, v_warning);
    dbms_lob.freetemporary(c);
    v_amount := DBMS_LOB.GETLENGTH(b);
--    dbms_output.put_line('L B'||v_amount);

    bret := decodeBase642Blob(b);
    dbms_lob.freetemporary(b);
    return bret;

  end decode;


end json_ext;

/
--------------------------------------------------------
--  DDL for Package Body JSON_HELPER
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_HELPER" as

  --recursive merge
  function merge( p_a_json json, p_b_json json) return json as
    l_json    JSON;
    l_jv      json_value;
    l_indx    number;
    l_recursive json_value;
  begin
    --
    -- Initialize our return object
    --
    l_json := p_a_json;

    -- loop through p_b_json
    l_indx := p_b_json.json_data.first;
    loop
      exit when l_indx is null;
      l_jv   := p_b_json.json_data(l_indx);
      if(l_jv.is_object) then
        --recursive
        l_recursive := l_json.get(l_jv.mapname);
        if(l_recursive is not null and l_recursive.is_object) then
          l_json.put(l_jv.mapname, merge(json(l_recursive), json(l_jv)));
        else
          l_json.put(l_jv.mapname, l_jv);
        end if;
      else
        l_json.put(l_jv.mapname, l_jv);
      end if;

      --increment
      l_indx := p_b_json.json_data.next(l_indx);
    end loop;

    return l_json;

  end merge;

  -- join two lists
  function join( p_a_list json_list, p_b_list json_list) return json_list as
    l_json_list json_list := p_a_list;
  begin
    for indx in 1 .. p_b_list.count loop
      l_json_list.append(p_b_list.get(indx));
    end loop;

    return l_json_list;

  end join;

  -- keep keys.
  function keep( p_json json, p_keys json_list) return json as
    l_json json := json();
    mapname varchar2(4000);
  begin
    for i in 1 .. p_keys.count loop
      mapname := p_keys.get(i).get_string;
      if(p_json.exist(mapname)) then
        l_json.put(mapname, p_json.get(mapname));
      end if;
    end loop;

    return l_json;
  end keep;

  -- drop keys.
  function remove( p_json json, p_keys json_list) return json as
    l_json json := p_json;
  begin
    for i in 1 .. p_keys.count loop
      l_json.remove(p_keys.get(i).get_string);
    end loop;

    return l_json;
  end remove;

  --equals functions

  function equals(p_v1 json_value, p_v2 number) return boolean as
  begin
    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(not p_v1.is_number) then
      return false;
    end if;

    return p_v2 = p_v1.get_number;
  end;

  function equals(p_v1 json_value, p_v2 boolean) return boolean as
  begin
    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(not p_v1.is_bool) then
      return false;
    end if;

    return p_v2 = p_v1.get_bool;
  end;

  function equals(p_v1 json_value, p_v2 varchar2) return boolean as
  begin
    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(not p_v1.is_string) then
      return false;
    end if;

    return p_v2 = p_v1.get_string;
  end;

  function equals(p_v1 json_value, p_v2 clob) return boolean as
    my_clob clob;
    res boolean;
  begin
    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(not p_v1.is_string) then
      return false;
    end if;

    my_clob := empty_clob();
    dbms_lob.createtemporary(my_clob, true);
    p_v1.get_string(my_clob);

    res := dbms_lob.compare(p_v2, my_clob) = 0;
    dbms_lob.freetemporary(my_clob);
  end;

  function equals(p_v1 json_value, p_v2 json_value, exact boolean) return boolean as
  begin
    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(p_v2.is_number) then return equals(p_v1, p_v2.get_number); end if;
    if(p_v2.is_bool) then return equals(p_v1, p_v2.get_bool); end if;
    if(p_v2.is_object) then return equals(p_v1, json(p_v2), exact); end if;
    if(p_v2.is_array) then return equals(p_v1, json_list(p_v2), exact); end if;
    if(p_v2.is_string) then
      if(p_v2.extended_str is null) then
        return equals(p_v1, p_v2.get_string);
      else
        declare
          my_clob clob; res boolean;
        begin
          my_clob := empty_clob();
          dbms_lob.createtemporary(my_clob, true);
          p_v2.get_string(my_clob);
          res := equals(p_v1, my_clob);
          dbms_lob.freetemporary(my_clob);
          return res;
        end;
      end if;
    end if;

    return false; --should never happen
  end;

  function equals(p_v1 json_value, p_v2 json_list, exact boolean) return boolean as
    cmp json_list;
    res boolean := true;
  begin
--  p_v1.print(false);
--  p_v2.print(false);
--  dbms_output.put_line('labc1'||case when exact then 'X' else 'U' end);

    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(not p_v1.is_array) then
      return false;
    end if;

--  dbms_output.put_line('labc2'||case when exact then 'X' else 'U' end);

    cmp := json_list(p_v1);
    if(cmp.count != p_v2.count and exact) then return false; end if;

--  dbms_output.put_line('labc3'||case when exact then 'X' else 'U' end);

    if(exact) then
      for i in 1 .. cmp.count loop
        res := equals(cmp.get(i), p_v2.get(i), exact);
        if(not res) then return res; end if;
      end loop;
    else
--  dbms_output.put_line('labc4'||case when exact then 'X' else 'U' end);
      if(p_v2.count > cmp.count) then return false; end if;
--  dbms_output.put_line('labc5'||case when exact then 'X' else 'U' end);

      --match sublist here!
      for x in 0 .. (cmp.count-p_v2.count) loop
--  dbms_output.put_line('labc7'||x);

        for i in 1 .. p_v2.count loop
          res := equals(cmp.get(x+i), p_v2.get(i), exact);
          if(not res) then
            goto next_index;
          end if;
        end loop;
        return true;

        <<next_index>>
        null;
      end loop;

--  dbms_output.put_line('labc7'||case when exact then 'X' else 'U' end);

    return false; --no match

    end if;

    return res;
  end;

  function equals(p_v1 json_value, p_v2 json, exact boolean) return boolean as
    cmp json;
    res boolean := true;
  begin
--  p_v1.print(false);
--  p_v2.print(false);
--  dbms_output.put_line('abc1');

    if(p_v2 is null) then
      return p_v1.is_null;
    end if;

    if(not p_v1.is_object) then
      return false;
    end if;

    cmp := json(p_v1);

--  dbms_output.put_line('abc2');

    if(cmp.count != p_v2.count and exact) then return false; end if;

--  dbms_output.put_line('abc3');
    declare
      k1 json_list := p_v2.get_keys;
      key_index number;
    begin
      for i in 1 .. k1.count loop
        key_index := cmp.index_of(k1.get(i).get_string);
        if(key_index = -1) then return false; end if;
        if(exact) then
          if(not equals(p_v2.get(i), cmp.get(key_index),true)) then return false; end if;
        else
          --non exact
          declare
            v1 json_value := cmp.get(key_index);
            v2 json_value := p_v2.get(i);
          begin
--  dbms_output.put_line('abc3 1/2');
--            v1.print(false);
--            v2.print(false);

            if(v1.is_object and v2.is_object) then
              if(not equals(v1, v2, false)) then return false; end if;
            elsif(v1.is_array and v2.is_array) then
              if(not equals(v1, v2, false)) then return false; end if;
            else
              if(not equals(v1, v2, true)) then return false; end if;
            end if;
          end;

        end if;
      end loop;
    end;

--  dbms_output.put_line('abc4');

    return true;
  end;

  function equals(p_v1 json, p_v2 json, exact boolean) return boolean as
  begin
    return equals(p_v1.to_json_value, p_v2, exact);
  end;

  function equals(p_v1 json_list, p_v2 json_list, exact boolean) return boolean as
  begin
    return equals(p_v1.to_json_value, p_v2, exact);
  end;

  --contain
  function contains(p_v1 json, p_v2 json_value, exact boolean) return boolean as
    v_values json_list;
  begin
    if(equals(p_v1.to_json_value, p_v2, exact)) then return true; end if;

    v_values := p_v1.get_values;

    for i in 1 .. v_values.count loop
      declare
        v_val json_value := v_values.get(i);
      begin
        if(v_val.is_object) then
          if(contains(json(v_val),p_v2,exact)) then return true; end if;
        end if;
        if(v_val.is_array) then
          if(contains(json_list(v_val),p_v2, exact)) then return true; end if;
        end if;

        if(equals(v_val, p_v2, exact)) then return true; end if;
      end;

    end loop;

    return false;
  end;

  function contains(p_v1 json_list, p_v2 json_value, exact boolean) return boolean as
  begin
    if(equals(p_v1.to_json_value, p_v2, exact)) then return true; end if;

    for i in 1 .. p_v1.count loop
      declare
        v_val json_value := p_v1.get(i);
      begin
        if(v_val.is_object) then
          if(contains(json(v_val),p_v2, exact)) then return true; end if;
        end if;
        if(v_val.is_array) then
          if(contains(json_list(v_val),p_v2, exact)) then return true; end if;
        end if;

        if(equals(v_val, p_v2, exact)) then return true; end if;
      end;

    end loop;

    return false;
  end;

  function contains(p_v1 json, p_v2 json, exact boolean ) return boolean as
  begin return contains(p_v1, p_v2.to_json_value,exact); end;
  function contains(p_v1 json, p_v2 json_list, exact boolean ) return boolean as
  begin return contains(p_v1, p_v2.to_json_value,exact); end;
  function contains(p_v1 json, p_v2 number, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;
  function contains(p_v1 json, p_v2 varchar2, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;
  function contains(p_v1 json, p_v2 boolean, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;
  function contains(p_v1 json, p_v2 clob, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;

  function contains(p_v1 json_list, p_v2 json, exact boolean ) return boolean as begin
  return contains(p_v1, p_v2.to_json_value,exact); end;
  function contains(p_v1 json_list, p_v2 json_list, exact boolean ) return boolean as begin
  return contains(p_v1, p_v2.to_json_value,exact); end;
  function contains(p_v1 json_list, p_v2 number, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;
  function contains(p_v1 json_list, p_v2 varchar2, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;
  function contains(p_v1 json_list, p_v2 boolean, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;
  function contains(p_v1 json_list, p_v2 clob, exact boolean ) return boolean as begin
  return contains(p_v1, json_value(p_v2),exact); end;


end json_helper;

/
--------------------------------------------------------
--  DDL for Package Body JSON_ML
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_ML" as
  function get_jsonml_stylesheet return xmltype;

  function xml2json(xml in xmltype) return json_list as
    l_json        xmltype;
    l_returnvalue clob;
  begin
    l_json := xml.transform (get_jsonml_stylesheet);
    l_returnvalue := l_json.getclobval();
    l_returnvalue := dbms_xmlgen.convert (l_returnvalue, dbms_xmlgen.entity_decode);
    --dbms_output.put_line(l_returnvalue);
    return json_list(l_returnvalue);
  end xml2json;

  function xmlstr2json(xmlstr in varchar2) return json_list as
  begin
    return xml2json(xmltype(xmlstr));
  end xmlstr2json;

  function get_jsonml_stylesheet return xmltype as
  begin
    if(jsonml_stylesheet is null) then
    jsonml_stylesheet := xmltype('<?xml version="1.0" encoding="UTF-8"?>
<!--
		JsonML.xslt

		Created: 2006-11-15-0551
		Modified: 2009-02-14-0927

		Released under an open-source license:
		http://jsonml.org/License.htm

		This transformation converts any XML document into JsonML.
		It omits processing-instructions and comment-nodes.

		To enable comment-nodes to be emitted as JavaScript comments,
		uncomment the Comment() template.
-->
<xsl:stylesheet version="1.0"
				xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<xsl:output method="text"
				media-type="application/json"
				encoding="UTF-8"
				indent="no"
				omit-xml-declaration="yes" />

	<!-- constants -->
	<xsl:variable name="XHTML"
				  select="''http://www.w3.org/1999/xhtml''" />

	<xsl:variable name="START_ELEM"
				  select="''[''" />

	<xsl:variable name="END_ELEM"
				  select="'']''" />

	<xsl:variable name="VALUE_DELIM"
				  select="'',''" />

	<xsl:variable name="START_ATTRIB"
				  select="''{''" />

	<xsl:variable name="END_ATTRIB"
				  select="''}''" />

	<xsl:variable name="NAME_DELIM"
				  select="'':''" />

	<xsl:variable name="STRING_DELIM"
				  select="''&#x22;''" />

	<xsl:variable name="START_COMMENT"
				  select="''/*''" />

	<xsl:variable name="END_COMMENT"
				  select="''*/''" />

	<!-- root-node -->
	<xsl:template match="/">
		<xsl:apply-templates select="*" />
	</xsl:template>

	<!-- comments -->
	<xsl:template match="comment()">
	<!-- uncomment to support JSON comments -->
	<!--
		<xsl:value-of select="$START_COMMENT" />

		<xsl:value-of select="."
					  disable-output-escaping="yes" />

		<xsl:value-of select="$END_COMMENT" />
	-->
	</xsl:template>

	<!-- elements -->
	<xsl:template match="*">
		<xsl:value-of select="$START_ELEM" />

		<!-- tag-name string -->
		<xsl:value-of select="$STRING_DELIM" />
		<xsl:choose>
			<xsl:when test="namespace-uri()=$XHTML">
				<xsl:value-of select="local-name()" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="name()" />
			</xsl:otherwise>
		</xsl:choose>
		<xsl:value-of select="$STRING_DELIM" />

		<!-- attribute object -->
		<xsl:if test="count(@*)>0">
			<xsl:value-of select="$VALUE_DELIM" />
			<xsl:value-of select="$START_ATTRIB" />
			<xsl:for-each select="@*">
				<xsl:if test="position()>1">
					<xsl:value-of select="$VALUE_DELIM" />
				</xsl:if>
				<xsl:apply-templates select="." />
			</xsl:for-each>
			<xsl:value-of select="$END_ATTRIB" />
		</xsl:if>

		<!-- child elements and text-nodes -->
		<xsl:for-each select="*|text()">
			<xsl:value-of select="$VALUE_DELIM" />
			<xsl:apply-templates select="." />
		</xsl:for-each>

		<xsl:value-of select="$END_ELEM" />
	</xsl:template>

	<!-- text-nodes -->
	<xsl:template match="text()">
		<xsl:call-template name="escape-string">
			<xsl:with-param name="value"
							select="." />
		</xsl:call-template>
	</xsl:template>

	<!-- attributes -->
	<xsl:template match="@*">
		<xsl:value-of select="$STRING_DELIM" />
		<xsl:choose>
			<xsl:when test="namespace-uri()=$XHTML">
				<xsl:value-of select="local-name()" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="name()" />
			</xsl:otherwise>
		</xsl:choose>
		<xsl:value-of select="$STRING_DELIM" />

		<xsl:value-of select="$NAME_DELIM" />

		<xsl:call-template name="escape-string">
			<xsl:with-param name="value"
							select="." />
		</xsl:call-template>

	</xsl:template>

	<!-- escape-string: quotes and escapes -->
	<xsl:template name="escape-string">
		<xsl:param name="value" />

		<xsl:value-of select="$STRING_DELIM" />

		<xsl:if test="string-length($value)>0">
			<xsl:variable name="escaped-whacks">
				<!-- escape backslashes -->
				<xsl:call-template name="string-replace">
					<xsl:with-param name="value"
									select="$value" />
					<xsl:with-param name="find"
									select="''\''" />
					<xsl:with-param name="replace"
									select="''\\''" />
				</xsl:call-template>
			</xsl:variable>

			<xsl:variable name="escaped-LF">
				<!-- escape line feeds -->
				<xsl:call-template name="string-replace">
					<xsl:with-param name="value"
									select="$escaped-whacks" />
					<xsl:with-param name="find"
									select="''&#x0A;''" />
					<xsl:with-param name="replace"
									select="''\n''" />
				</xsl:call-template>
			</xsl:variable>

			<xsl:variable name="escaped-CR">
				<!-- escape carriage returns -->
				<xsl:call-template name="string-replace">
					<xsl:with-param name="value"
									select="$escaped-LF" />
					<xsl:with-param name="find"
									select="''&#x0D;''" />
					<xsl:with-param name="replace"
									select="''\r''" />
				</xsl:call-template>
			</xsl:variable>

			<xsl:variable name="escaped-tabs">
				<!-- escape tabs -->
				<xsl:call-template name="string-replace">
					<xsl:with-param name="value"
									select="$escaped-CR" />
					<xsl:with-param name="find"
									select="''&#x09;''" />
					<xsl:with-param name="replace"
									select="''\t''" />
				</xsl:call-template>
			</xsl:variable>

			<!-- escape quotes -->
			<xsl:call-template name="string-replace">
				<xsl:with-param name="value"
								select="$escaped-tabs" />
				<xsl:with-param name="find"
								select="''&quot;''" />
				<xsl:with-param name="replace"
								select="''\&quot;''" />
			</xsl:call-template>
		</xsl:if>

		<xsl:value-of select="$STRING_DELIM" />
	</xsl:template>

	<!-- string-replace: replaces occurances of one string with another -->
	<xsl:template name="string-replace">
		<xsl:param name="value" />
		<xsl:param name="find" />
		<xsl:param name="replace" />

		<xsl:choose>
			<xsl:when test="contains($value,$find)">
				<!-- replace and call recursively on next -->
				<xsl:value-of select="substring-before($value,$find)"
							  disable-output-escaping="yes" />
				<xsl:value-of select="$replace"
							  disable-output-escaping="yes" />
				<xsl:call-template name="string-replace">
					<xsl:with-param name="value"
									select="substring-after($value,$find)" />
					<xsl:with-param name="find"
									select="$find" />
					<xsl:with-param name="replace"
									select="$replace" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<!-- no replacement necessary -->
				<xsl:value-of select="$value"
							  disable-output-escaping="yes" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

</xsl:stylesheet>');
    end if;
    return jsonml_stylesheet;
  end get_jsonml_stylesheet;

end json_ml;

/
--------------------------------------------------------
--  DDL for Package Body JSON_PARSER
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_PARSER" as
  /*
  Copyright (c) 2009 Jonas Krogsboell

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  */

  decimalpoint varchar2(1 char) := '.';

  procedure updateDecimalPoint as
  begin
    SELECT substr(VALUE,1,1) into decimalpoint FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS';
  end updateDecimalPoint;

  /*type json_src is record (len number, offset number, src varchar2(10), s_clob clob); */
  function next_char(indx number, s in out nocopy json_src) return varchar2 as
  begin
    if(indx > s.len) then return null; end if;
    --right offset?
    if(indx > 4000 + s.offset or indx < s.offset) then
    --load right offset
      s.offset := indx - (indx mod 4000);
      s.src := dbms_lob.substr(s.s_clob, 4000, s.offset+1);
    end if;
    --read from s.src
    return substr(s.src, indx-s.offset, 1);
  end;

  function next_char2(indx number, s in out nocopy json_src, amount number default 1) return varchar2 as
    buf varchar2(32767) := '';
  begin
    for i in 1..amount loop
      buf := buf || next_char(indx-1+i,s);
    end loop;
    return buf;
  end;

  function prepareClob(buf clob) return json_parser.json_src as
    temp json_parser.json_src;
  begin
    temp.s_clob := buf;
    temp.offset := 0;
    temp.src := dbms_lob.substr(buf, 4000, temp.offset+1);
    temp.len := dbms_lob.getlength(buf);
    return temp;
  end;

  function prepareVarchar2(buf varchar2) return json_parser.json_src as
    temp json_parser.json_src;
  begin
    temp.s_clob := buf;
    temp.offset := 0;
    temp.src := substr(buf, 1, 4000);
    temp.len := length(buf);
    return temp;
  end;

  procedure debug(text varchar2) as
  begin
    dbms_output.put_line(text);
  end;

  procedure print_token(t rToken) as
  begin
    dbms_output.put_line('Line: '||t.line||' - Column: '||t.col||' - Type: '||t.type_name||' - Content: '||t.data);
  end print_token;

  /* SCANNER FUNCTIONS START */
  procedure s_error(text varchar2, line number, col number) as
  begin
    raise_application_error(-20100, 'JSON Scanner exception @ line: '||line||' column: '||col||' - '||text);
  end;

  procedure s_error(text varchar2, tok rToken) as
  begin
    raise_application_error(-20100, 'JSON Scanner exception @ line: '||tok.line||' column: '||tok.col||' - '||text);
  end;

  function mt(t varchar2, l pls_integer, c pls_integer, d varchar2) return rToken as
    token rToken;
  begin
    token.type_name := t;
    token.line := l;
    token.col := c;
    token.data := d;
    return token;
  end;

  function lexNumber(jsrc in out nocopy json_src, tok in out nocopy rToken, indx in out nocopy pls_integer) return pls_integer as
    numbuf varchar2(4000) := '';
    buf varchar2(4);
    checkLoop boolean;
  begin
    buf := next_char(indx, jsrc);
    if(buf = '-') then numbuf := '-'; indx := indx + 1; end if;
    buf := next_char(indx, jsrc);
    --0 or [1-9]([0-9])*
    if(buf = '0') then
      numbuf := numbuf || '0'; indx := indx + 1;
      buf := next_char(indx, jsrc);
    elsif(buf >= '1' and buf <= '9') then
      numbuf := numbuf || buf; indx := indx + 1;
      --read digits
      buf := next_char(indx, jsrc);
      while(buf >= '0' and buf <= '9') loop
        numbuf := numbuf || buf; indx := indx + 1;
        buf := next_char(indx, jsrc);
      end loop;
    end if;
    --fraction
    if(buf = '.') then
      numbuf := numbuf || buf; indx := indx + 1;
      buf := next_char(indx, jsrc);
      checkLoop := FALSE;
      while(buf >= '0' and buf <= '9') loop
        checkLoop := TRUE;
        numbuf := numbuf || buf; indx := indx + 1;
        buf := next_char(indx, jsrc);
      end loop;
      if(not checkLoop) then
        s_error('Expected: digits in fraction', tok);
      end if;
    end if;
    --exp part
    if(buf in ('e', 'E')) then
      numbuf := numbuf || buf; indx := indx + 1;
      buf := next_char(indx, jsrc);
      if(buf = '+' or buf = '-') then
        numbuf := numbuf || buf; indx := indx + 1;
        buf := next_char(indx, jsrc);
      end if;
      checkLoop := FALSE;
      while(buf >= '0' and buf <= '9') loop
        checkLoop := TRUE;
        numbuf := numbuf || buf; indx := indx + 1;
        buf := next_char(indx, jsrc);
      end loop;
      if(not checkLoop) then
        s_error('Expected: digits in exp', tok);
      end if;
    end if;

    tok.data := numbuf;
    return indx;
  end lexNumber;

  -- [a-zA-Z]([a-zA-Z0-9])*
  function lexName(jsrc in out nocopy json_src, tok in out nocopy rToken, indx in out nocopy pls_integer) return pls_integer as
    varbuf varchar2(32767) := '';
    buf varchar(4);
    num number;
  begin
    buf := next_char(indx, jsrc);
    while(REGEXP_LIKE(buf, '^[[:alnum:]\_]$', 'i')) loop
      varbuf := varbuf || buf;
      indx := indx + 1;
      buf := next_char(indx, jsrc);
      if (buf is null) then
        goto retname;
        --debug('Premature string ending');
      end if;
    end loop;
    <<retname>>

    --could check for reserved keywords here

    --debug(varbuf);
    tok.data := varbuf;
    return indx-1;
  end lexName;

  procedure updateClob(v_extended in out nocopy clob, v_str varchar2) as
  begin
    dbms_lob.writeappend(v_extended, length(v_str), v_str);
  end updateClob;

  function lexString(jsrc in out nocopy json_src, tok in out nocopy rToken, indx in out nocopy pls_integer, endChar char) return pls_integer as
    v_extended clob := null; v_count number := 0;
    varbuf varchar2(32767) := '';
    buf varchar(4);
    wrong boolean;
  begin
    indx := indx +1;
    buf := next_char(indx, jsrc);
    while(buf != endChar) loop
      --clob control
      if(v_count > 8191) then --crazy oracle error (16383 is the highest working length with unistr - 8192 choosen to be safe)
        if(v_extended is null) then
          v_extended := empty_clob();
          dbms_lob.createtemporary(v_extended, true);
        end if;
        updateClob(v_extended, unistr(varbuf));
        varbuf := ''; v_count := 0;
      end if;
      if(buf = Chr(13) or buf = CHR(9) or buf = CHR(10)) then
        s_error('Control characters not allowed (CHR(9),CHR(10)CHR(13))', tok);
      end if;
      if(buf = '\') then
        --varbuf := varbuf || buf;
        indx := indx + 1;
        buf := next_char(indx, jsrc);
        case
          when buf in ('\') then
            varbuf := varbuf || buf || buf; v_count := v_count + 2;
            indx := indx + 1;
            buf := next_char(indx, jsrc);
          when buf in ('"', '/') then
            varbuf := varbuf || buf; v_count := v_count + 1;
            indx := indx + 1;
            buf := next_char(indx, jsrc);
          when buf = '''' then
            if(json_strict = false) then
              varbuf := varbuf || buf; v_count := v_count + 1;
              indx := indx + 1;
              buf := next_char(indx, jsrc);
            else
              s_error('strictmode - expected: " \ / b f n r t u ', tok);
            end if;
          when buf in ('b', 'f', 'n', 'r', 't') then
            --backspace b = U+0008
            --formfeed  f = U+000C
            --newline   n = U+000A
            --carret    r = U+000D
            --tabulator t = U+0009
            case buf
            when 'b' then varbuf := varbuf || chr(8);
            when 'f' then varbuf := varbuf || chr(13);
            when 'n' then varbuf := varbuf || chr(10);
            when 'r' then varbuf := varbuf || chr(14);
            when 't' then varbuf := varbuf || chr(9);
            end case;
            --varbuf := varbuf || buf;
            v_count := v_count + 1;
            indx := indx + 1;
            buf := next_char(indx, jsrc);
          when buf = 'u' then
            --four hexidecimal chars
            declare
              four varchar2(4);
            begin
              four := next_char2(indx+1, jsrc, 4);
              wrong := FALSE;
              if(upper(substr(four, 1,1)) not in ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f')) then wrong := TRUE; end if;
              if(upper(substr(four, 2,1)) not in ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f')) then wrong := TRUE; end if;
              if(upper(substr(four, 3,1)) not in ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f')) then wrong := TRUE; end if;
              if(upper(substr(four, 4,1)) not in ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f')) then wrong := TRUE; end if;
              if(wrong) then
                s_error('expected: " \u([0-9][A-F]){4}', tok);
              end if;
--              varbuf := varbuf || buf || four;
              varbuf := varbuf || '\'||four;--chr(to_number(four,'XXXX'));
               v_count := v_count + 5;
              indx := indx + 5;
              buf := next_char(indx, jsrc);
              end;
          else
            s_error('expected: " \ / b f n r t u ', tok);
        end case;
      else
        varbuf := varbuf || buf; v_count := v_count + 1;
        indx := indx + 1;
        buf := next_char(indx, jsrc);
      end if;
    end loop;

    if (buf is null) then
      s_error('string ending not found', tok);
      --debug('Premature string ending');
    end if;

    --debug(varbuf);
    --dbms_output.put_line(varbuf);
    if(v_extended is not null) then
      updateClob(v_extended, unistr(varbuf));
      tok.data_overflow := v_extended;
      tok.data := dbms_lob.substr(v_extended, 1, 32767);
    else
      tok.data := unistr(varbuf);
    end if;
    return indx;
  end lexString;

  /* scanner tokens:
    '{', '}', ',', ':', '[', ']', STRING, NUMBER, TRUE, FALSE, NULL
  */
  function lexer(jsrc in out nocopy json_src) return lTokens as
    tokens lTokens;
    indx pls_integer := 1;
    tok_indx pls_integer := 1;
    buf varchar2(4);
    lin_no number := 1;
    col_no number := 0;
  begin
    while (indx <= jsrc.len) loop
      --read into buf
      buf := next_char(indx, jsrc);
      col_no := col_no + 1;
      --convert to switch case
      case
        when buf = '{' then tokens(tok_indx) := mt('{', lin_no, col_no, null); tok_indx := tok_indx + 1;
        when buf = '}' then tokens(tok_indx) := mt('}', lin_no, col_no, null); tok_indx := tok_indx + 1;
        when buf = ',' then tokens(tok_indx) := mt(',', lin_no, col_no, null); tok_indx := tok_indx + 1;
        when buf = ':' then tokens(tok_indx) := mt(':', lin_no, col_no, null); tok_indx := tok_indx + 1;
        when buf = '[' then tokens(tok_indx) := mt('[', lin_no, col_no, null); tok_indx := tok_indx + 1;
        when buf = ']' then tokens(tok_indx) := mt(']', lin_no, col_no, null); tok_indx := tok_indx + 1;
        when buf = 't' then
          if(next_char2(indx, jsrc, 4) != 'true') then
            if(json_strict = false and REGEXP_LIKE(buf, '^[[:alpha:]]$', 'i')) then
              tokens(tok_indx) := mt('STRING', lin_no, col_no, null);
              indx := lexName(jsrc, tokens(tok_indx), indx);
              col_no := col_no + length(tokens(tok_indx).data) + 1;
              tok_indx := tok_indx + 1;
            else
              s_error('Expected: ''true''', lin_no, col_no);
            end if;
          else
            tokens(tok_indx) := mt('TRUE', lin_no, col_no, null); tok_indx := tok_indx + 1;
            indx := indx + 3;
            col_no := col_no + 3;
          end if;
        when buf = 'n' then
          if(next_char2(indx, jsrc, 4) != 'null') then
            if(json_strict = false and REGEXP_LIKE(buf, '^[[:alpha:]]$', 'i')) then
              tokens(tok_indx) := mt('STRING', lin_no, col_no, null);
              indx := lexName(jsrc, tokens(tok_indx), indx);
              col_no := col_no + length(tokens(tok_indx).data) + 1;
              tok_indx := tok_indx + 1;
            else
              s_error('Expected: ''null''', lin_no, col_no);
            end if;
          else
            tokens(tok_indx) := mt('NULL', lin_no, col_no, null); tok_indx := tok_indx + 1;
            indx := indx + 3;
            col_no := col_no + 3;
          end if;
        when buf = 'f' then
          if(next_char2(indx, jsrc, 5) != 'false') then
            if(json_strict = false and REGEXP_LIKE(buf, '^[[:alpha:]]$', 'i')) then
              tokens(tok_indx) := mt('STRING', lin_no, col_no, null);
              indx := lexName(jsrc, tokens(tok_indx), indx);
              col_no := col_no + length(tokens(tok_indx).data) + 1;
              tok_indx := tok_indx + 1;
            else
              s_error('Expected: ''false''', lin_no, col_no);
            end if;
          else
            tokens(tok_indx) := mt('FALSE', lin_no, col_no, null); tok_indx := tok_indx + 1;
            indx := indx + 4;
            col_no := col_no + 4;
          end if;
        /*   -- 9 = TAB, 10 = \n, 13 = \r (Linux = \n, Windows = \r\n, Mac = \r */
        when (buf = Chr(10)) then --linux newlines
          lin_no := lin_no + 1;
          col_no := 0;

        when (buf = Chr(13)) then --Windows or Mac way
          lin_no := lin_no + 1;
          col_no := 0;
          if(jsrc.len >= indx +1) then -- better safe than sorry
            buf := next_char(indx+1, jsrc);
            if(buf = Chr(10)) then --\r\n
              indx := indx + 1;
            end if;
          end if;

        when (buf = CHR(9)) then null; --tabbing
        when (buf in ('-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')) then --number
          tokens(tok_indx) := mt('NUMBER', lin_no, col_no, null);
          indx := lexNumber(jsrc, tokens(tok_indx), indx)-1;
          col_no := col_no + length(tokens(tok_indx).data);
          tok_indx := tok_indx + 1;
        when buf = '"' then --number
          tokens(tok_indx) := mt('STRING', lin_no, col_no, null);
          indx := lexString(jsrc, tokens(tok_indx), indx, '"');
          col_no := col_no + length(tokens(tok_indx).data) + 1;
          tok_indx := tok_indx + 1;
        when buf = '''' and json_strict = false then --number
          tokens(tok_indx) := mt('STRING', lin_no, col_no, null);
          indx := lexString(jsrc, tokens(tok_indx), indx, '''');
          col_no := col_no + length(tokens(tok_indx).data) + 1; --hovsa her
          tok_indx := tok_indx + 1;
        when json_strict = false and REGEXP_LIKE(buf, '^[[:alpha:]]$', 'i') then
          tokens(tok_indx) := mt('STRING', lin_no, col_no, null);
          indx := lexName(jsrc, tokens(tok_indx), indx);
          if(tokens(tok_indx).data_overflow is not null) then
            col_no := col_no + dbms_lob.getlength(tokens(tok_indx).data_overflow) + 1;
          else
            col_no := col_no + length(tokens(tok_indx).data) + 1;
          end if;
          tok_indx := tok_indx + 1;
        when json_strict = false and buf||next_char(indx+1, jsrc) = '/*' then --strip comments
          declare
            saveindx number := indx;
            un_esc clob;
          begin
            indx := indx + 1;
            loop
              indx := indx + 1;
              buf := next_char(indx, jsrc)||next_char(indx+1, jsrc);
              exit when buf = '*/';
              exit when buf is null;
            end loop;

            if(indx = saveindx+2) then
              --enter unescaped mode
              --dbms_output.put_line('Entering unescaped mode');
              un_esc := empty_clob();
              dbms_lob.createtemporary(un_esc, true);
              indx := indx + 1;
              loop
                indx := indx + 1;
                buf := next_char(indx, jsrc)||next_char(indx+1, jsrc)||next_char(indx+2, jsrc)||next_char(indx+3, jsrc);
                exit when buf = '/**/';
                if buf is null then
                  s_error('Unexpected sequence /**/ to end unescaped data: '||buf, lin_no, col_no);
                end if;
                buf := next_char(indx, jsrc);
                dbms_lob.writeappend(un_esc, length(buf), buf);
              end loop;
              tokens(tok_indx) := mt('ESTRING', lin_no, col_no, null);
              tokens(tok_indx).data_overflow := un_esc;
              col_no := col_no + dbms_lob.getlength(un_esc) + 1; --note: line count won't work properly
              tok_indx := tok_indx + 1;
              indx := indx + 2;
            end if;

            indx := indx + 1;
          end;
        when buf = ' ' then null; --space
        else
          s_error('Unexpected char: '||buf, lin_no, col_no);
      end case;

      indx := indx + 1;
    end loop;

    return tokens;
  end lexer;

  /* SCANNER END */

  /* PARSER FUNCTIONS START*/
  procedure p_error(text varchar2, tok rToken) as
  begin
    raise_application_error(-20101, 'JSON Parser exception @ line: '||tok.line||' column: '||tok.col||' - '||text);
  end;

  function parseObj(tokens lTokens, indx in out nocopy pls_integer) return json;

  function parseArr(tokens lTokens, indx in out nocopy pls_integer) return json_list as
    e_arr json_value_array := json_value_array();
    ret_list json_list := json_list();
    v_count number := 0;
    tok rToken;
  begin
    --value, value, value ]
    if(indx > tokens.count) then p_error('more elements in array was excepted', tok); end if;
    tok := tokens(indx);
    while(tok.type_name != ']') loop
      e_arr.extend;
      v_count := v_count + 1;
      case tok.type_name
        when 'TRUE' then e_arr(v_count) := json_value(true);
        when 'FALSE' then e_arr(v_count) := json_value(false);
        when 'NULL' then e_arr(v_count) := json_value;
        when 'STRING' then e_arr(v_count) := case when tok.data_overflow is not null then json_value(tok.data_overflow) else json_value(tok.data) end;
        when 'ESTRING' then e_arr(v_count) := json_value(tok.data_overflow, false);
        when 'NUMBER' then e_arr(v_count) := json_value(to_number(replace(tok.data, '.', decimalpoint)));
        when '[' then
          declare e_list json_list; begin
            indx := indx + 1;
            e_list := parseArr(tokens, indx);
            e_arr(v_count) := e_list.to_json_value;
          end;
        when '{' then
          indx := indx + 1;
          e_arr(v_count) := parseObj(tokens, indx).to_json_value;
        else
          p_error('Expected a value', tok);
      end case;
      indx := indx + 1;
      if(indx > tokens.count) then p_error('] not found', tok); end if;
      tok := tokens(indx);
      if(tok.type_name = ',') then --advance
        indx := indx + 1;
        if(indx > tokens.count) then p_error('more elements in array was excepted', tok); end if;
        tok := tokens(indx);
        if(tok.type_name = ']') then --premature exit
          p_error('Premature exit in array', tok);
        end if;
      elsif(tok.type_name != ']') then --error
        p_error('Expected , or ]', tok);
      end if;

    end loop;
    ret_list.list_data := e_arr;
    return ret_list;
  end parseArr;

  function parseMem(tokens lTokens, indx in out pls_integer, mem_name varchar2, mem_indx number) return json_value as
    mem json_value;
    tok rToken;
  begin
    tok := tokens(indx);
    case tok.type_name
      when 'TRUE' then mem := json_value(true);
      when 'FALSE' then mem := json_value(false);
      when 'NULL' then mem := json_value;
      when 'STRING' then mem := case when tok.data_overflow is not null then json_value(tok.data_overflow) else json_value(tok.data) end;
      when 'ESTRING' then mem := json_value(tok.data_overflow, false);
      when 'NUMBER' then mem := json_value(to_number(replace(tok.data, '.', decimalpoint)));
      when '[' then
        declare
          e_list json_list;
        begin
          indx := indx + 1;
          e_list := parseArr(tokens, indx);
          mem := e_list.to_json_value;
        end;
      when '{' then
        indx := indx + 1;
        mem := parseObj(tokens, indx).to_json_value;
      else
        p_error('Found '||tok.type_name, tok);
    end case;
    mem.mapname := mem_name;
    mem.mapindx := mem_indx;

    indx := indx + 1;
    return mem;
  end parseMem;

  /*procedure test_duplicate_members(arr in json_member_array, mem_name in varchar2, wheretok rToken) as
  begin
    for i in 1 .. arr.count loop
      if(arr(i).member_name = mem_name) then
        p_error('Duplicate member name', wheretok);
      end if;
    end loop;
  end test_duplicate_members;*/

  function parseObj(tokens lTokens, indx in out nocopy pls_integer) return json as
    type memmap is table of number index by varchar2(4000); -- i've read somewhere that this is not possible - but it is!
    mymap memmap;
    nullelemfound boolean := false;

    obj json;
    tok rToken;
    mem_name varchar(4000);
    arr json_value_array := json_value_array();
  begin
    --what to expect?
    while(indx <= tokens.count) loop
      tok := tokens(indx);
      --debug('E: '||tok.type_name);
      case tok.type_name
      when 'STRING' then
        --member
        mem_name := substr(tok.data, 1, 4000);
        begin
          if(mem_name is null) then
            if(nullelemfound) then
              p_error('Duplicate empty member: ', tok);
            else
              nullelemfound := true;
            end if;
          elsif(mymap(mem_name) is not null) then
            p_error('Duplicate member name: '||mem_name, tok);
          end if;
        exception
          when no_data_found then mymap(mem_name) := 1;
        end;

        indx := indx + 1;
        if(indx > tokens.count) then p_error('Unexpected end of input', tok); end if;
        tok := tokens(indx);
        indx := indx + 1;
        if(indx > tokens.count) then p_error('Unexpected end of input', tok); end if;
        if(tok.type_name = ':') then
          --parse
          declare
            jmb json_value;
            x number;
          begin
            x := arr.count + 1;
            jmb := parseMem(tokens, indx, mem_name, x);
            arr.extend;
            arr(x) := jmb;
          end;
        else
          p_error('Expected '':''', tok);
        end if;
        --move indx forward if ',' is found
        if(indx > tokens.count) then p_error('Unexpected end of input', tok); end if;

        tok := tokens(indx);
        if(tok.type_name = ',') then
          --debug('found ,');
          indx := indx + 1;
          tok := tokens(indx);
          if(tok.type_name = '}') then --premature exit
            p_error('Premature exit in json object', tok);
          end if;
        elsif(tok.type_name != '}') then
           p_error('A comma seperator is probably missing', tok);
        end if;
      when '}' then
        obj := json();
        obj.json_data := arr;
        return obj;
      else
        p_error('Expected string or }', tok);
      end case;
    end loop;

    p_error('} not found', tokens(indx-1));

    return obj;

  end;

  function parser(str varchar2) return json as
    tokens lTokens;
    obj json;
    indx pls_integer := 1;
    jsrc json_src;
  begin
    updateDecimalPoint();
    jsrc := prepareVarchar2(str);
    tokens := lexer(jsrc);
    if(tokens(indx).type_name = '{') then
      indx := indx + 1;
      obj := parseObj(tokens, indx);
    else
      raise_application_error(-20101, 'JSON Parser exception - no { start found');
    end if;
    if(tokens.count != indx) then
      p_error('} should end the JSON object', tokens(indx));
    end if;

    return obj;
  end parser;

  function parse_list(str varchar2) return json_list as
    tokens lTokens;
    obj json_list;
    indx pls_integer := 1;
    jsrc json_src;
  begin
    updateDecimalPoint();
    jsrc := prepareVarchar2(str);
    tokens := lexer(jsrc);
    if(tokens(indx).type_name = '[') then
      indx := indx + 1;
      obj := parseArr(tokens, indx);
    else
      raise_application_error(-20101, 'JSON List Parser exception - no [ start found');
    end if;
    if(tokens.count != indx) then
      p_error('] should end the JSON List object', tokens(indx));
    end if;

    return obj;
  end parse_list;

  function parse_list(str clob) return json_list as
    tokens lTokens;
    obj json_list;
    indx pls_integer := 1;
    jsrc json_src;
  begin
    updateDecimalPoint();
    jsrc := prepareClob(str);
    tokens := lexer(jsrc);
    if(tokens(indx).type_name = '[') then
      indx := indx + 1;
      obj := parseArr(tokens, indx);
    else
      raise_application_error(-20101, 'JSON List Parser exception - no [ start found');
    end if;
    if(tokens.count != indx) then
      p_error('] should end the JSON List object', tokens(indx));
    end if;

    return obj;
  end parse_list;

  function parser(str clob) return json as
    tokens lTokens;
    obj json;
    indx pls_integer := 1;
    jsrc json_src;
  begin
    updateDecimalPoint();
    --dbms_output.put_line('Using clob');
    jsrc := prepareClob(str);
    tokens := lexer(jsrc);
    if(tokens(indx).type_name = '{') then
      indx := indx + 1;
      obj := parseObj(tokens, indx);
    else
      raise_application_error(-20101, 'JSON Parser exception - no { start found');
    end if;
    if(tokens.count != indx) then
      p_error('} should end the JSON object', tokens(indx));
    end if;

    return obj;
  end parser;

  function parse_any(str varchar2) return json_value as
    tokens lTokens;
    obj json_list;
    ret json_value;
    indx pls_integer := 1;
    jsrc json_src;
  begin
    updateDecimalPoint();
    jsrc := prepareVarchar2(str);
    tokens := lexer(jsrc);
    tokens(tokens.count+1).type_name := ']';
    obj := parseArr(tokens, indx);
    if(tokens.count != indx) then
      p_error('] should end the JSON List object', tokens(indx));
    end if;

    return obj.head();
  end parse_any;

  function parse_any(str clob) return json_value as
    tokens lTokens;
    obj json_list;
    indx pls_integer := 1;
    jsrc json_src;
  begin
    jsrc := prepareClob(str);
    tokens := lexer(jsrc);
    tokens(tokens.count+1).type_name := ']';
    obj := parseArr(tokens, indx);
    if(tokens.count != indx) then
      p_error('] should end the JSON List object', tokens(indx));
    end if;

    return obj.head();
  end parse_any;

  /* last entry is the one to keep */
  procedure remove_duplicates(obj in out nocopy json) as
    type memberlist is table of json_value index by varchar2(4000);
    members memberlist;
    nulljsonvalue json_value := null;
    validated json := json();
    indx varchar2(4000);
  begin
    for i in 1 .. obj.count loop
      if(obj.get(i).mapname is null) then
        nulljsonvalue := obj.get(i);
      else
        members(obj.get(i).mapname) := obj.get(i);
      end if;
    end loop;

    validated.check_duplicate(false);
    indx := members.first;
    loop
      exit when indx is null;
      validated.put(indx, members(indx));
      indx := members.next(indx);
    end loop;
    if(nulljsonvalue is not null) then
      validated.put('', nulljsonvalue);
    end if;

    validated.check_for_duplicate := obj.check_for_duplicate;

    obj := validated;
  end;

  function get_version return varchar2 as
  begin
    return 'PL/JSON v1.0.4';
  end get_version;

end json_parser;

/
--------------------------------------------------------
--  DDL for Package Body JSON_PRINTER
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_PRINTER" as
  max_line_len number := 0;
  cur_line_len number := 0;

  function llcheck(str in varchar2) return varchar2 as
  begin
    --dbms_output.put_line(cur_line_len || ' : '|| str);
    if(max_line_len > 0 and length(str)+cur_line_len > max_line_len) then
      cur_line_len := length(str);
      return newline_char || str;
    else
      cur_line_len := cur_line_len + length(str);
      return str;
    end if;
  end llcheck;

  function escapeString(str varchar2) return varchar2 as
    sb varchar2(32767) := '';
    buf varchar2(40);
    num number;
  begin
    if(str is null) then return ''; end if;
    for i in 1 .. length(str) loop
      buf := substr(str, i, 1);
      --backspace b = U+0008
      --formfeed  f = U+000C
      --newline   n = U+000A
      --carret    r = U+000D
      --tabulator t = U+0009
      case buf
      when chr( 8) then buf := '\b';
      when chr( 9) then buf := '\t';
      when chr(10) then buf := '\n';
      when chr(13) then buf := '\f';
      when chr(14) then buf := '\r';
      when chr(34) then buf := '\"';
      when chr(47) then if(escape_solidus) then buf := '\/'; end if;
      when chr(92) then buf := '\\';
      else
        if(ascii(buf) < 32) then
          buf := '\u'||replace(substr(to_char(ascii(buf), 'XXXX'),2,4), ' ', '0');
        elsif (ascii_output) then
          buf := replace(asciistr(buf), '\', '\u');
        end if;
      end case;

      sb := sb || buf;
    end loop;

    return sb;
  end escapeString;

  function newline(spaces boolean) return varchar2 as
  begin
    cur_line_len := 0;
    if(spaces) then return newline_char; else return ''; end if;
  end;

/*  function get_schema return varchar2 as
  begin
    return sys_context('userenv', 'current_schema');
  end;
*/
  function tab(indent number, spaces boolean) return varchar2 as
    i varchar(200) := '';
  begin
    if(not spaces) then return ''; end if;
    for x in 1 .. indent loop i := i || indent_string; end loop;
    return i;
  end;

  function getCommaSep(spaces boolean) return varchar2 as
  begin
    if(spaces) then return ', '; else return ','; end if;
  end;

  function getMemName(mem json_value, spaces boolean) return varchar2 as
  begin
    if(spaces) then
      return llcheck('"'||escapeString(mem.mapname)||'"') || llcheck(' : ');
    else
      return llcheck('"'||escapeString(mem.mapname)||'"') || llcheck(':');
    end if;
  end;

/* Clob method start here */
  procedure add_to_clob(buf_lob in out nocopy clob, buf_str in out nocopy varchar2, str varchar2) as
  begin
    if(lengthb(str) > 32767 - lengthb(buf_str)) then
--      dbms_lob.append(buf_lob, buf_str);
      dbms_lob.writeappend(buf_lob, length(buf_str), buf_str);
      buf_str := str;
    else
      buf_str := buf_str || str;
    end if;
  end add_to_clob;

  procedure flush_clob(buf_lob in out nocopy clob, buf_str in out nocopy varchar2) as
  begin
--    dbms_lob.append(buf_lob, buf_str);
    dbms_lob.writeappend(buf_lob, length(buf_str), buf_str);
  end flush_clob;

  procedure ppObj(obj json, indent number, buf in out nocopy clob, spaces boolean, buf_str in out nocopy varchar2);

  procedure ppEA(input json_list, indent number, buf in out nocopy clob, spaces boolean, buf_str in out nocopy varchar2) as
    elem json_value;
    arr json_value_array := input.list_data;
    numbuf varchar2(4000);
  begin
    for y in 1 .. arr.count loop
      elem := arr(y);
      if(elem is not null) then
      case elem.get_type
        when 'number' then
          numbuf := '';
          if (elem.get_number < 1 and elem.get_number > 0) then numbuf := '0'; end if;
          if (elem.get_number < 0 and elem.get_number > -1) then
            numbuf := '-0';
            numbuf := numbuf || substr(to_char(elem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''),2);
          else
            numbuf := numbuf || to_char(elem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''');
          end if;
          add_to_clob(buf, buf_str, llcheck(numbuf));
        when 'string' then
          if(elem.extended_str is not null) then --clob implementation
            add_to_clob(buf, buf_str, case when elem.num = 1 then '"' else '/**/' end);
            declare
              offset number := 1;
              v_str varchar(32767);
              amount number := 32767;
            begin
              while(offset <= dbms_lob.getlength(elem.extended_str)) loop
                dbms_lob.read(elem.extended_str, amount, offset, v_str);
                if(elem.num = 1) then
                  add_to_clob(buf, buf_str, escapeString(v_str));
                else
                  add_to_clob(buf, buf_str, v_str);
                end if;
                offset := offset + amount;
              end loop;
            end;
            add_to_clob(buf, buf_str, case when elem.num = 1 then '"' else '/**/' end || newline_char);
          else
            if(elem.num = 1) then
              add_to_clob(buf, buf_str, llcheck('"'||escapeString(elem.get_string)||'"'));
            else
              add_to_clob(buf, buf_str, llcheck('/**/'||elem.get_string||'/**/'));
            end if;
          end if;
        when 'bool' then
          if(elem.get_bool) then
            add_to_clob(buf, buf_str, llcheck('true'));
          else
            add_to_clob(buf, buf_str, llcheck('false'));
          end if;
        when 'null' then
          add_to_clob(buf, buf_str, llcheck('null'));
        when 'array' then
          add_to_clob(buf, buf_str, llcheck('['));
          ppEA(json_list(elem), indent, buf, spaces, buf_str);
          add_to_clob(buf, buf_str, llcheck(']'));
        when 'object' then
          ppObj(json(elem), indent, buf, spaces, buf_str);
        else add_to_clob(buf, buf_str, llcheck(elem.get_type));
      end case;
      end if;
      if(y != arr.count) then add_to_clob(buf, buf_str, llcheck(getCommaSep(spaces))); end if;
    end loop;
  end ppEA;

  procedure ppMem(mem json_value, indent number, buf in out nocopy clob, spaces boolean, buf_str in out nocopy varchar2) as
    numbuf varchar2(4000);
  begin
    add_to_clob(buf, buf_str, llcheck(tab(indent, spaces)) || llcheck(getMemName(mem, spaces)));
    case mem.get_type
      when 'number' then
        if (mem.get_number < 1 and mem.get_number > 0) then numbuf := '0'; end if;
        if (mem.get_number < 0 and mem.get_number > -1) then
          numbuf := '-0';
          numbuf := numbuf || substr(to_char(mem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''),2);
        else
          numbuf := numbuf || to_char(mem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''');
        end if;
        add_to_clob(buf, buf_str, llcheck(numbuf));
      when 'string' then
        if(mem.extended_str is not null) then --clob implementation
          add_to_clob(buf, buf_str, case when mem.num = 1 then '"' else '/**/' end);
          declare
            offset number := 1;
            v_str varchar(32767);
            amount number := 32767;
          begin
--            dbms_output.put_line('SIZE:'||dbms_lob.getlength(mem.extended_str));
            while(offset <= dbms_lob.getlength(mem.extended_str)) loop
--            dbms_output.put_line('OFFSET:'||offset);
 --             v_str := dbms_lob.substr(mem.extended_str, 8192, offset);
              dbms_lob.read(mem.extended_str, amount, offset, v_str);
--            dbms_output.put_line('VSTR_SIZE:'||length(v_str));
              if(mem.num = 1) then
                add_to_clob(buf, buf_str, escapeString(v_str));
              else
                add_to_clob(buf, buf_str, v_str);
              end if;
              offset := offset + amount;
            end loop;
          end;
          add_to_clob(buf, buf_str, case when mem.num = 1 then '"' else '/**/' end || newline_char);
        else
          if(mem.num = 1) then
            add_to_clob(buf, buf_str, llcheck('"'||escapeString(mem.get_string)||'"'));
          else
            add_to_clob(buf, buf_str, llcheck('/**/'||mem.get_string||'/**/'));
          end if;
        end if;
      when 'bool' then
        if(mem.get_bool) then
          add_to_clob(buf, buf_str, llcheck('true'));
        else
          add_to_clob(buf, buf_str, llcheck('false'));
        end if;
      when 'null' then
        add_to_clob(buf, buf_str, llcheck('null'));
      when 'array' then
        add_to_clob(buf, buf_str, llcheck('['));
        ppEA(json_list(mem), indent, buf, spaces, buf_str);
        add_to_clob(buf, buf_str, llcheck(']'));
      when 'object' then
        ppObj(json(mem), indent, buf, spaces, buf_str);
      else add_to_clob(buf, buf_str, llcheck(mem.get_type));
    end case;
  end ppMem;

  procedure ppObj(obj json, indent number, buf in out nocopy clob, spaces boolean, buf_str in out nocopy varchar2) as
  begin
    add_to_clob(buf, buf_str, llcheck('{') || newline(spaces));
    for m in 1 .. obj.json_data.count loop
      ppMem(obj.json_data(m), indent+1, buf, spaces, buf_str);
      if(m != obj.json_data.count) then
        add_to_clob(buf, buf_str, llcheck(',') || newline(spaces));
      else
        add_to_clob(buf, buf_str, newline(spaces));
      end if;
    end loop;
    add_to_clob(buf, buf_str, llcheck(tab(indent, spaces)) || llcheck('}')); -- || chr(13);
  end ppObj;

  procedure pretty_print(obj json, spaces boolean default true, buf in out nocopy clob, line_length number default 0, erase_clob boolean default true) as
    buf_str varchar2(32767);
    amount number := dbms_lob.getlength(buf);
  begin
    if(erase_clob and amount > 0) then dbms_lob.trim(buf, 0); dbms_lob.erase(buf, amount); end if;

    max_line_len := line_length;
    cur_line_len := 0;
    ppObj(obj, 0, buf, spaces, buf_str);
    flush_clob(buf, buf_str);
  end;

  procedure pretty_print_list(obj json_list, spaces boolean default true, buf in out nocopy clob, line_length number default 0, erase_clob boolean default true) as
    buf_str varchar2(32767);
    amount number := dbms_lob.getlength(buf);
  begin
    if(erase_clob and amount > 0) then dbms_lob.trim(buf, 0); dbms_lob.erase(buf, amount); end if;

    max_line_len := line_length;
    cur_line_len := 0;
    add_to_clob(buf, buf_str, llcheck('['));
    ppEA(obj, 0, buf, spaces, buf_str);
    add_to_clob(buf, buf_str, llcheck(']'));
    flush_clob(buf, buf_str);
  end;

  procedure pretty_print_any(json_part json_value, spaces boolean default true, buf in out nocopy clob, line_length number default 0, erase_clob boolean default true) as
    buf_str varchar2(32767) := '';
    numbuf varchar2(4000);
    amount number := dbms_lob.getlength(buf);
  begin
    if(erase_clob and amount > 0) then dbms_lob.trim(buf, 0); dbms_lob.erase(buf, amount); end if;

    case json_part.get_type
      when 'number' then
        if (json_part.get_number < 1 and json_part.get_number > 0) then numbuf := '0'; end if;
        if (json_part.get_number < 0 and json_part.get_number > -1) then
          numbuf := '-0';
          numbuf := numbuf || substr(to_char(json_part.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''),2);
        else
          numbuf := numbuf || to_char(json_part.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''');
        end if;
        add_to_clob(buf, buf_str, numbuf);
      when 'string' then
        if(json_part.extended_str is not null) then --clob implementation
          add_to_clob(buf, buf_str, case when json_part.num = 1 then '"' else '/**/' end);
          declare
            offset number := 1;
            v_str varchar(32767);
            amount number := 32767;
          begin
            while(offset <= dbms_lob.getlength(json_part.extended_str)) loop
              dbms_lob.read(json_part.extended_str, amount, offset, v_str);
              if(json_part.num = 1) then
                add_to_clob(buf, buf_str, escapeString(v_str));
              else
                add_to_clob(buf, buf_str, v_str);
              end if;
              offset := offset + amount;
            end loop;
          end;
          add_to_clob(buf, buf_str, case when json_part.num = 1 then '"' else '/**/' end);
        else
          if(json_part.num = 1) then
            add_to_clob(buf, buf_str, llcheck('"'||escapeString(json_part.get_string)||'"'));
          else
            add_to_clob(buf, buf_str, llcheck('/**/'||json_part.get_string||'/**/'));
          end if;
        end if;
      when 'bool' then
	      if(json_part.get_bool) then
          add_to_clob(buf, buf_str, 'true');
        else
          add_to_clob(buf, buf_str, 'false');
        end if;
      when 'null' then
        add_to_clob(buf, buf_str, 'null');
      when 'array' then
        pretty_print_list(json_list(json_part), spaces, buf, line_length);
        return;
      when 'object' then
        pretty_print(json(json_part), spaces, buf, line_length);
        return;
      else add_to_clob(buf, buf_str, 'unknown type:'|| json_part.get_type);
    end case;
    flush_clob(buf, buf_str);
  end;

/* Clob method end here */

/* Varchar2 method start here */

  procedure ppObj(obj json, indent number, buf in out nocopy varchar2, spaces boolean);

  procedure ppEA(input json_list, indent number, buf in out varchar2, spaces boolean) as
    elem json_value;
    arr json_value_array := input.list_data;
    str varchar2(400);
  begin
    for y in 1 .. arr.count loop
      elem := arr(y);
      if(elem is not null) then
      case elem.get_type
        when 'number' then
          str := '';
          if (elem.get_number < 1 and elem.get_number > 0) then str := '0'; end if;
          if (elem.get_number < 0 and elem.get_number > -1) then
            str := '-0' || substr(to_char(elem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''),2);
          else
            str := str || to_char(elem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''');
          end if;
          buf := buf || llcheck(str);
        when 'string' then
          if(elem.num = 1) then
            buf := buf || llcheck('"'||escapeString(elem.get_string)||'"');
          else
            buf := buf || llcheck('/**/'||elem.get_string||'/**/');
          end if;
        when 'bool' then
          if(elem.get_bool) then
            buf := buf || llcheck('true');
          else
            buf := buf || llcheck('false');
          end if;
        when 'null' then
          buf := buf || llcheck('null');
        when 'array' then
          buf := buf || llcheck('[');
          ppEA(json_list(elem), indent, buf, spaces);
          buf := buf || llcheck(']');
        when 'object' then
          ppObj(json(elem), indent, buf, spaces);
        else buf := buf || llcheck(elem.get_type); /* should never happen */
      end case;
      end if;
      if(y != arr.count) then buf := buf || llcheck(getCommaSep(spaces)); end if;
    end loop;
  end ppEA;

  procedure ppMem(mem json_value, indent number, buf in out nocopy varchar2, spaces boolean) as
    str varchar2(400) := '';
  begin
    buf := buf || llcheck(tab(indent, spaces)) || getMemName(mem, spaces);
    case mem.get_type
      when 'number' then
        if (mem.get_number < 1 and mem.get_number > 0) then str := '0'; end if;
        if (mem.get_number < 0 and mem.get_number > -1) then
          str := '-0' || substr(to_char(mem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''),2);
        else
          str := str || to_char(mem.get_number, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''');
        end if;
        buf := buf || llcheck(str);
      when 'string' then
        if(mem.num = 1) then
          buf := buf || llcheck('"'||escapeString(mem.get_string)||'"');
        else
          buf := buf || llcheck('/**/'||mem.get_string||'/**/');
        end if;
      when 'bool' then
        if(mem.get_bool) then
          buf := buf || llcheck('true');
        else
          buf := buf || llcheck('false');
        end if;
      when 'null' then
        buf := buf || llcheck('null');
      when 'array' then
        buf := buf || llcheck('[');
        ppEA(json_list(mem), indent, buf, spaces);
        buf := buf || llcheck(']');
      when 'object' then
        ppObj(json(mem), indent, buf, spaces);
      else buf := buf || llcheck(mem.get_type); /* should never happen */
    end case;
  end ppMem;

  procedure ppObj(obj json, indent number, buf in out nocopy varchar2, spaces boolean) as
  begin
    buf := buf || llcheck('{') || newline(spaces);
    for m in 1 .. obj.json_data.count loop
      ppMem(obj.json_data(m), indent+1, buf, spaces);
      if(m != obj.json_data.count) then buf := buf || llcheck(',') || newline(spaces);
      else buf := buf || newline(spaces); end if;
    end loop;
    buf := buf || llcheck(tab(indent, spaces)) || llcheck('}'); -- || chr(13);
  end ppObj;

  function pretty_print(obj json, spaces boolean default true, line_length number default 0) return varchar2 as
    buf varchar2(32767) := '';
  begin
    max_line_len := line_length;
    cur_line_len := 0;
    ppObj(obj, 0, buf, spaces);
    return buf;
  end pretty_print;

  function pretty_print_list(obj json_list, spaces boolean default true, line_length number default 0) return varchar2 as
    buf varchar2(32767);
  begin
    max_line_len := line_length;
    cur_line_len := 0;
    buf := llcheck('[');
    ppEA(obj, 0, buf, spaces);
    buf := buf || llcheck(']');
    return buf;
  end;

  function pretty_print_any(json_part json_value, spaces boolean default true, line_length number default 0) return varchar2 as
    buf varchar2(32767) := '';
  begin
    case json_part.get_type
      when 'number' then
        if (json_part.get_number() < 1 and json_part.get_number() > 0) then buf := buf || '0'; end if;
        if (json_part.get_number() < 0 and json_part.get_number() > -1) then
          buf := buf || '-0';
          buf := buf || substr(to_char(json_part.get_number(), 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,'''),2);
        else
          buf := buf || to_char(json_part.get_number(), 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''');
        end if;
      when 'string' then
        if(json_part.num = 1) then
          buf := buf || '"'||escapeString(json_part.get_string)||'"';
        else
          buf := buf || '/**/'||json_part.get_string||'/**/';
        end if;
      when 'bool' then
      	if(json_part.get_bool) then buf := 'true'; else buf := 'false'; end if;
      when 'null' then
        buf := 'null';
      when 'array' then
        buf := pretty_print_list(json_list(json_part), spaces, line_length);
      when 'object' then
        buf := pretty_print(json(json_part), spaces, line_length);
      else buf := 'weird error: '|| json_part.get_type;
    end case;
    return buf;
  end;

  procedure dbms_output_clob(my_clob clob, delim varchar2, jsonp varchar2 default null) as
    prev number := 1;
    indx number := 1;
    size_of_nl number := lengthb(delim);
    v_str varchar2(32767);
    amount number := 32767;
  begin
    if(jsonp is not null) then dbms_output.put_line(jsonp||'('); end if;
    while(indx != 0) loop
      --read every line
      indx := dbms_lob.instr(my_clob, delim, prev+1);
 --     dbms_output.put_line(prev || ' to ' || indx);

      if(indx = 0) then
        --emit from prev to end;
        amount := 32767;
 --       dbms_output.put_line(' mycloblen ' || dbms_lob.getlength(my_clob));
        loop
          dbms_lob.read(my_clob, amount, prev, v_str);
          dbms_output.put_line(v_str);
          prev := prev+amount-1;
          exit when prev >= dbms_lob.getlength(my_clob);
        end loop;
      else
        amount := indx - prev;
        if(amount > 32767) then
          amount := 32767;
--          dbms_output.put_line(' mycloblen ' || dbms_lob.getlength(my_clob));
          loop
            dbms_lob.read(my_clob, amount, prev, v_str);
            dbms_output.put_line(v_str);
            prev := prev+amount-1;
            amount := indx - prev;
            exit when prev >= indx - 1;
            if(amount > 32767) then amount := 32767; end if;
          end loop;
          prev := indx + size_of_nl;
        else
          dbms_lob.read(my_clob, amount, prev, v_str);
          dbms_output.put_line(v_str);
          prev := indx + size_of_nl;
        end if;
      end if;

    end loop;
    if(jsonp is not null) then dbms_output.put_line(')'); end if;

/*    while (amount != 0) loop
      indx := dbms_lob.instr(my_clob, delim, prev+1);

--      dbms_output.put_line(prev || ' to ' || indx);
      if(indx = 0) then
        indx := dbms_lob.getlength(my_clob)+1;
      end if;

      if(indx-prev > 32767) then
        indx := prev+32767;
      end if;
--      dbms_output.put_line(prev || ' to ' || indx);
      --substr doesnt work properly on all platforms! (come on oracle - error on Oracle VM for virtualbox)
--        dbms_output.put_line(dbms_lob.substr(my_clob, indx-prev, prev));
      amount := indx-prev;
--        dbms_output.put_line('amount'||amount);
      dbms_lob.read(my_clob, amount, prev, v_str);
      dbms_output.put_line(v_str);
      prev := indx+size_of_nl;
      if(amount = 32767) then prev := prev-size_of_nl-1; end if;
    end loop;
    if(jsonp is not null) then dbms_output.put_line(')'); end if;*/
  end;


/*  procedure dbms_output_clob(my_clob clob, delim varchar2, jsonp varchar2 default null) as
    prev number := 1;
    indx number := 1;
    size_of_nl number := lengthb(delim);
    v_str varchar2(32767);
    amount number;
  begin
    if(jsonp is not null) then dbms_output.put_line(jsonp||'('); end if;
    while (indx != 0) loop
      indx := dbms_lob.instr(my_clob, delim, prev+1);

--      dbms_output.put_line(prev || ' to ' || indx);
      if(indx-prev > 32767) then
        indx := prev+32767;
      end if;
--      dbms_output.put_line(prev || ' to ' || indx);
      --substr doesnt work properly on all platforms! (come on oracle - error on Oracle VM for virtualbox)
      if(indx = 0) then
--        dbms_output.put_line(dbms_lob.substr(my_clob, dbms_lob.getlength(my_clob)-prev+size_of_nl, prev));
        amount := dbms_lob.getlength(my_clob)-prev+size_of_nl;
        dbms_lob.read(my_clob, amount, prev, v_str);
      else
--        dbms_output.put_line(dbms_lob.substr(my_clob, indx-prev, prev));
        amount := indx-prev;
--        dbms_output.put_line('amount'||amount);
        dbms_lob.read(my_clob, amount, prev, v_str);
      end if;
      dbms_output.put_line(v_str);
      prev := indx+size_of_nl;
      if(amount = 32767) then prev := prev-size_of_nl-1; end if;
    end loop;
    if(jsonp is not null) then dbms_output.put_line(')'); end if;
  end;
*/
  procedure htp_output_clob(my_clob clob, jsonp varchar2 default null) as
    /*amount number := 4096;
    pos number := 1;
    len number;
    */
    l_amt    number default 30;
    l_off   number default 1;
    l_str   varchar2(4096);

  begin
    if(jsonp is not null) then htp.prn(jsonp||'('); end if;

    begin
      loop
        dbms_lob.read( my_clob, l_amt, l_off, l_str );

        -- it is vital to use htp.PRN to avoid
        -- spurious line feeds getting added to your
        -- document
        htp.prn( l_str  );
        l_off := l_off+l_amt;
        l_amt := 4096;
      end loop;
    exception
      when no_data_found then NULL;
    end;

    /*
    len := dbms_lob.getlength(my_clob);

    while(pos < len) loop
      htp.prn(dbms_lob.substr(my_clob, amount, pos)); -- should I replace substr with dbms_lob.read?
      --dbms_output.put_line(dbms_lob.substr(my_clob, amount, pos));
      pos := pos + amount;
    end loop;
    */
    if(jsonp is not null) then htp.prn(')'); end if;
  end;

end json_printer;

/
--------------------------------------------------------
--  DDL for Package Body JSON_UTIL_PKG
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_UTIL_PKG" 
as
  scanner_exception exception;
  pragma exception_init(scanner_exception, -20100);
  parser_exception exception;
  pragma exception_init(parser_exception, -20101);

  /*

  Purpose:    JSON utilities for PL/SQL

  Remarks:

  Who     Date        Description
  ------  ----------  -------------------------------------
  MBR     30.01.2010  Created

  */


  g_json_null_object             constant varchar2(20) := '{ }';


function get_xml_to_json_stylesheet return varchar2
as
begin

  /*

  Purpose:    return XSLT stylesheet for XML to JSON transformation

  Remarks:    see http://code.google.com/p/xml2json-xslt/

  Who     Date        Description
  ------  ----------  -------------------------------------
  MBR     30.01.2010  Created
  MBR     30.01.2010  Added fix for nulls

  */


  return q'^<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
  Copyright (c) 2006,2008 Doeke Zanstra
  All rights reserved.

  Redistribution and use in source and binary forms, with or without modification,
  are permitted provided that the following conditions are met:

  Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer. Redistributions in binary
  form must reproduce the above copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other materials provided with
  the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  THE POSSIBILITY OF SUCH DAMAGE.
-->

  <xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="text/x-json"/>
        <xsl:strip-space elements="*"/>
  <!--contant-->
  <xsl:variable name="d">0123456789</xsl:variable>

  <!-- ignore document text -->
  <xsl:template match="text()[preceding-sibling::node() or following-sibling::node()]"/>

  <!-- string -->
  <xsl:template match="text()">
    <xsl:call-template name="escape-string">
      <xsl:with-param name="s" select="."/>
    </xsl:call-template>
  </xsl:template>

  <!-- Main template for escaping strings; used by above template and for object-properties
       Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
  <xsl:template name="escape-string">
    <xsl:param name="s"/>
    <xsl:text>"</xsl:text>
    <xsl:call-template name="escape-bs-string">
      <xsl:with-param name="s" select="$s"/>
    </xsl:call-template>
    <xsl:text>"</xsl:text>
  </xsl:template>

  <!-- Escape the backslash (\) before everything else. -->
  <xsl:template name="escape-bs-string">
    <xsl:param name="s"/>
    <xsl:choose>
      <xsl:when test="contains($s,'\')">
        <xsl:call-template name="escape-quot-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/>
        </xsl:call-template>
        <xsl:call-template name="escape-bs-string">
          <xsl:with-param name="s" select="substring-after($s,'\')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="escape-quot-string">
          <xsl:with-param name="s" select="$s"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- Escape the double quote ("). -->
  <xsl:template name="escape-quot-string">
    <xsl:param name="s"/>
    <xsl:choose>
      <xsl:when test="contains($s,'&quot;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&quot;'),'\&quot;')"/>
        </xsl:call-template>
        <xsl:call-template name="escape-quot-string">
          <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="$s"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- Replace tab, line feed and/or carriage return by its matching escape code. Can't escape backslash
       or double quote here, because they don't replace characters (&#x0; becomes \t), but they prefix
       characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be
       processed first. This function can't do that. -->
  <xsl:template name="encode-string">
    <xsl:param name="s"/>
    <xsl:choose>
      <!-- tab -->
      <xsl:when test="contains($s,'&#x9;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&#x9;'),'\t',substring-after($s,'&#x9;'))"/>
        </xsl:call-template>
      </xsl:when>
      <!-- line feed -->
      <xsl:when test="contains($s,'&#xA;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&#xA;'),'\n',substring-after($s,'&#xA;'))"/>
        </xsl:call-template>
      </xsl:when>
      <!-- carriage return -->
      <xsl:when test="contains($s,'&#xD;')">
        <xsl:call-template name="encode-string">
          <xsl:with-param name="s" select="concat(substring-before($s,'&#xD;'),'\r',substring-after($s,'&#xD;'))"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- number (no support for javascript mantissa) -->
  <xsl:template match="text()[not(string(number())='NaN' or
                      (starts-with(.,'0' ) and . != '0' and
not(starts-with(.,'0.' ))) or
                      (starts-with(.,'-0' ) and . != '-0' and
not(starts-with(.,'-0.' )))
                      )]">
    <xsl:value-of select="."/>
  </xsl:template>

  <!-- boolean, case-insensitive -->
  <xsl:template match="text()[translate(.,'TRUE','true')='true']">true</xsl:template>
  <xsl:template match="text()[translate(.,'FALSE','false')='false']">false</xsl:template>

  <!-- object -->
  <xsl:template match="*" name="base">
    <xsl:if test="not(preceding-sibling::*)">{</xsl:if>
    <xsl:call-template name="escape-string">
      <xsl:with-param name="s" select="name()"/>
    </xsl:call-template>
    <xsl:text>:</xsl:text>
    <!-- check type of node -->
    <xsl:choose>
      <!-- null nodes -->
      <xsl:when test="count(child::node())=0">null</xsl:when>
      <!-- other nodes -->
      <xsl:otherwise>
        <xsl:apply-templates select="child::node()"/>
      </xsl:otherwise>
    </xsl:choose>
    <!-- end of type check -->
    <xsl:if test="following-sibling::*">,</xsl:if>
    <xsl:if test="not(following-sibling::*)">}</xsl:if>
  </xsl:template>

  <!-- array -->
  <xsl:template match="*[count(../*[name(../*)=name(.)])=count(../*) and count(../*)&gt;1]">
    <xsl:if test="not(preceding-sibling::*)">[</xsl:if>
    <xsl:choose>
      <xsl:when test="not(child::node())">
        <xsl:text>null</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="child::node()"/>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="following-sibling::*">,</xsl:if>
    <xsl:if test="not(following-sibling::*)">]</xsl:if>
  </xsl:template>

  <!-- convert root element to an anonymous container -->
  <xsl:template match="/">
    <xsl:apply-templates select="node()"/>
  </xsl:template>

</xsl:stylesheet>^';

end get_xml_to_json_stylesheet;


function ref_cursor_to_json (p_ref_cursor in sys_refcursor,
                             p_max_rows in number := null,
                             p_skip_rows in number := null) return json_list
as
  l_ctx         dbms_xmlgen.ctxhandle;
  l_num_rows    pls_integer;
  l_xml         xmltype;
  l_json        xmltype;
  l_returnvalue clob;
begin

  /*

  Purpose:    generate JSON from REF Cursor

  Remarks:

  Who     Date        Description
  ------  ----------  -------------------------------------
  MBR     30.01.2010  Created
  JKR     01.05.2010  Edited to fit in PL/JSON

  */

  l_ctx := dbms_xmlgen.newcontext (p_ref_cursor);

  dbms_xmlgen.setnullhandling (l_ctx, dbms_xmlgen.empty_tag);

  -- for pagination

  if p_max_rows is not null then
    dbms_xmlgen.setmaxrows (l_ctx, p_max_rows);
  end if;

  if p_skip_rows is not null then
    dbms_xmlgen.setskiprows (l_ctx, p_skip_rows);
  end if;

  -- get the XML content
  l_xml := dbms_xmlgen.getxmltype (l_ctx, dbms_xmlgen.none);

  l_num_rows := dbms_xmlgen.getnumrowsprocessed (l_ctx);

  dbms_xmlgen.closecontext (l_ctx);

  close p_ref_cursor;

  if l_num_rows > 0 then
    -- perform the XSL transformation
    l_json := l_xml.transform (xmltype(get_xml_to_json_stylesheet));
    l_returnvalue := l_json.getclobval();
  else
    l_returnvalue := g_json_null_object;
  end if;

  l_returnvalue := dbms_xmlgen.convert (l_returnvalue, dbms_xmlgen.entity_decode);

  if(l_num_rows = 0) then
    return json_list();
  else
    if(l_num_rows = 1) then
      declare ret json_list := json_list();
      begin
        ret.append(
          json(
            json(l_returnvalue).get('ROWSET')
          ).get('ROW')
        );
        return ret;
      end;
    else
      return json_list(json(l_returnvalue).get('ROWSET'));
    end if;
  end if;

exception
  when scanner_exception then
    dbms_output.put('Scanner problem with the following input: ');
    dbms_output.put_line(l_returnvalue);
    raise;
  when parser_exception then
    dbms_output.put('Parser problem with the following input: ');
    dbms_output.put_line(l_returnvalue);
    raise;
  when others then raise;
end ref_cursor_to_json;

function sql_to_json (p_sql in varchar2,
                      p_max_rows in number := null,
                      p_skip_rows in number := null) return json_list
as
  v_cur sys_refcursor;
begin
  open v_cur for p_sql;
  return ref_cursor_to_json(v_cur, p_max_rows, p_skip_rows);

end sql_to_json;


end json_util_pkg;

/
--------------------------------------------------------
--  DDL for Package Body JSON_XML
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."JSON_XML" as

  function escapeStr(str varchar2) return varchar2 as
    buf varchar2(32767) := '';
    ch varchar2(4);
  begin
    for i in 1 .. length(str) loop
      ch := substr(str, i, 1);
      case ch
      when '&' then buf := buf || '&amp;';
      when '<' then buf := buf || '&lt;';
      when '>' then buf := buf || '&gt;';
      when '"' then buf := buf || '&quot;';
      else buf := buf || ch;
      end case;
    end loop;
    return buf;
  end escapeStr;

/* Clob methods from printer */
  procedure add_to_clob(buf_lob in out nocopy clob, buf_str in out nocopy varchar2, str varchar2) as
  begin
    if(length(str) > 32767 - length(buf_str)) then
      dbms_lob.append(buf_lob, buf_str);
      buf_str := str;
    else
      buf_str := buf_str || str;
    end if;
  end add_to_clob;

  procedure flush_clob(buf_lob in out nocopy clob, buf_str in out nocopy varchar2) as
  begin
    dbms_lob.append(buf_lob, buf_str);
  end flush_clob;

  procedure toString(obj json_value, tagname in varchar2, xmlstr in out nocopy clob, xmlbuf in out nocopy varchar2) as
    v_obj json;
    v_list json_list;

    v_keys json_list;
    v_value json_value;
    key_str varchar2(4000);
  begin
    if (obj.is_object()) then
      add_to_clob(xmlstr, xmlbuf, '<' || tagname || '>');
      v_obj := json(obj);

      v_keys := v_obj.get_keys();
      for i in 1 .. v_keys.count loop
        v_value := v_obj.get(i);
        key_str := v_keys.get(i).str;

        if(key_str = 'content') then
          if(v_value.is_array()) then
            declare
              v_l json_list := json_list(v_value);
            begin
              for j in 1 .. v_l.count loop
                if(j > 1) then add_to_clob(xmlstr, xmlbuf, chr(13)||chr(10)); end if;
                add_to_clob(xmlstr, xmlbuf, escapeStr(v_l.get(j).to_char()));
              end loop;
            end;
          else
            add_to_clob(xmlstr, xmlbuf, escapeStr(v_value.to_char()));
          end if;
        elsif(v_value.is_array()) then
          declare
            v_l json_list := json_list(v_value);
          begin
            for j in 1 .. v_l.count loop
              v_value := v_l.get(j);
              if(v_value.is_array()) then
                add_to_clob(xmlstr, xmlbuf, '<' || key_str || '>');
                add_to_clob(xmlstr, xmlbuf, escapeStr(v_value.to_char()));
                add_to_clob(xmlstr, xmlbuf, '</' || key_str || '>');
              else
                toString(v_value, key_str, xmlstr, xmlbuf);
              end if;
            end loop;
          end;
        elsif(v_value.is_null() or (v_value.is_string and v_value.get_string = '')) then
          add_to_clob(xmlstr, xmlbuf, '<' || key_str || '/>');
        else
          toString(v_value, key_str, xmlstr, xmlbuf);
        end if;
      end loop;

      add_to_clob(xmlstr, xmlbuf, '</' || tagname || '>');
    elsif (obj.is_array()) then
      v_list := json_list(obj);
      for i in 1 .. v_list.count loop
        v_value := v_list.get(i);
        toString(v_value, nvl(tagname, 'array'), xmlstr, xmlbuf);
      end loop;
    else
      add_to_clob(xmlstr, xmlbuf, '<' || tagname || '>'||escapeStr(obj.to_char())||'</' || tagname || '>');
    end if;
  end toString;

  function json_to_xml(obj json, tagname varchar2 default 'root') return xmltype as
    xmlstr clob := empty_clob();
    xmlbuf varchar2(32767) := '';
    returnValue xmltype;
  begin
    dbms_lob.createtemporary(xmlstr, true);

    toString(obj.to_json_value(), tagname, xmlstr, xmlbuf);

    flush_clob(xmlstr, xmlbuf);
    returnValue := xmltype('<?xml version="1.0"?>'||xmlstr);
    dbms_lob.freetemporary(xmlstr);
    return returnValue;
  end;

end json_xml;

/
--------------------------------------------------------
--  DDL for Package Body MOBILE_TEACHER_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."MOBILE_TEACHER_TAPI" 
IS
  -- insert
PROCEDURE ins(
    p_MAJOR       IN MOBILE_TEACHER.MAJOR%type DEFAULT NULL ,
    p_TEACHERNAME IN MOBILE_TEACHER.TEACHERNAME%type DEFAULT NULL ,
    p_RECORD_ID   IN MOBILE_TEACHER.RECORD_ID%type ,
    p_GENDER      IN MOBILE_TEACHER.GENDER%type DEFAULT NULL ,
    p_TEACHERNO   IN MOBILE_TEACHER.TEACHERNO%type DEFAULT NULL ,
    p_LESSON      IN MOBILE_TEACHER.LESSON%type DEFAULT NULL )
IS
BEGIN
  INSERT
  INTO MOBILE_TEACHER
    (
      MAJOR ,
      TEACHERNAME ,
      RECORD_ID ,
      GENDER ,
      TEACHERNO ,
      LESSON
    )
    VALUES
    (
      p_MAJOR ,
      p_TEACHERNAME ,
      p_RECORD_ID ,
      p_GENDER ,
      p_TEACHERNO ,
      p_LESSON
    );
END;
-- update
PROCEDURE upd
  (
    p_MAJOR       IN MOBILE_TEACHER.MAJOR%type DEFAULT NULL ,
    p_TEACHERNAME IN MOBILE_TEACHER.TEACHERNAME%type DEFAULT NULL ,
    p_RECORD_ID   IN MOBILE_TEACHER.RECORD_ID%type ,
    p_GENDER      IN MOBILE_TEACHER.GENDER%type DEFAULT NULL ,
    p_TEACHERNO   IN MOBILE_TEACHER.TEACHERNO%type DEFAULT NULL ,
    p_LESSON      IN MOBILE_TEACHER.LESSON%type DEFAULT NULL
  )
IS
BEGIN
  UPDATE MOBILE_TEACHER
  SET MAJOR       = p_MAJOR ,
    TEACHERNAME   = p_TEACHERNAME ,
    GENDER        = p_GENDER ,
    TEACHERNO     = p_TEACHERNO ,
    LESSON        = p_LESSON
  WHERE RECORD_ID = p_RECORD_ID;
END;
-- del
PROCEDURE del(
    p_RECORD_ID IN MOBILE_TEACHER.RECORD_ID%type )
IS
BEGIN
  DELETE FROM MOBILE_TEACHER WHERE RECORD_ID = p_RECORD_ID;
END;
END MOBILE_TEACHER_tapi;

/
--------------------------------------------------------
--  DDL for Package Body SCHOOL_NOTIFICATION_TAPI
--------------------------------------------------------

  CREATE OR REPLACE PACKAGE BODY "SYSTEM"."SCHOOL_NOTIFICATION_TAPI" 
IS
  -- insert
PROCEDURE ins(
      p_NOTIFICATIONCONTENT       IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATIONCONTENT%type DEFAULT NULL ,
      p_NOFIFICATION_TITLE        IN MOBILE_SCHOOL_NOTIFICATION.NOFIFICATION_TITLE%type DEFAULT NULL ,
      p_AUTHORID                  IN MOBILE_SCHOOL_NOTIFICATION.AUTHORID%type DEFAULT NULL ,
      p_NOTIFICATION_TYPE_ID      IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATION_TYPE_ID%type DEFAULT NULL ,
       P_REFURL                    IN MOBILE_SCHOOL_NOTIFICATION.REFURL%TYPE DEFAULT '',
      p_notified_user in number,
      op_op_code out number
     
  )
IS
t_next_id   COMMON_ACTIVITY.RECORD_ID%type;
t_message nvarchar2(200);
BEGIN
t_next_id :=CA_SEQ_SCHOOL_NOTIFICATION.nextval;
  INSERT
  INTO MOBILE_SCHOOL_NOTIFICATION
    (
      NOTIFICATIONCONTENT ,
      NOTIFICATION_PUBLISH_DATE ,
      NOFIFICATION_TITLE ,
      AUTHORID ,
      NOTIFICATION_TYPE_ID ,
      NOTIFICATION_ID,
      REFURL
    )
    VALUES
    (
      p_NOTIFICATIONCONTENT ,
      TO_CHAR(SYSDATE(),'yyyy-mm-dd hh24:mi'),
      p_NOFIFICATION_TITLE ,
      p_AUTHORID ,
      p_NOTIFICATION_TYPE_ID ,
      t_next_id,
      P_REFURL
    );
    
     --提醒用户
    if p_notified_user = 1 then
      begin
         CA_MESSAGES_tapi.INS(
              5,
              '*',
              p_NOFIFICATION_TITLE,
              t_next_id
            );
      
      end;
    end if;
    
    
    commit;
    op_op_code:=1;
exception
  when others then
    op_op_code:=-1;
    t_message:='code:'||sqlcode||'msg:'||sqlerrm;
END;
-- update
PROCEDURE upd
  (
    p_NOTIFICATIONCONTENT       IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATIONCONTENT%type DEFAULT NULL ,
    p_NOTIFICATION_PUBLISH_DATE IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATION_PUBLISH_DATE%type DEFAULT NULL ,
    p_NOFIFICATION_TITLE        IN MOBILE_SCHOOL_NOTIFICATION.NOFIFICATION_TITLE%type DEFAULT NULL ,
    p_AUTHORID                  IN MOBILE_SCHOOL_NOTIFICATION.AUTHORID%type DEFAULT NULL ,
    p_NOTIFICATION_TYPE_ID      IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATION_TYPE_ID%type DEFAULT NULL ,
    p_NOTIFICATION_ID           IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATION_ID%type
  )
IS
BEGIN
  UPDATE MOBILE_SCHOOL_NOTIFICATION
  SET NOTIFICATIONCONTENT     = p_NOTIFICATIONCONTENT ,
    NOTIFICATION_PUBLISH_DATE = p_NOTIFICATION_PUBLISH_DATE ,
    NOFIFICATION_TITLE        = p_NOFIFICATION_TITLE ,
    AUTHORID                  = p_AUTHORID ,
    NOTIFICATION_TYPE_ID      = p_NOTIFICATION_TYPE_ID
  WHERE NOTIFICATION_ID       = p_NOTIFICATION_ID;
END;
-- del
PROCEDURE del(
    p_NOTIFICATION_ID IN MOBILE_SCHOOL_NOTIFICATION.NOTIFICATION_ID%type )
IS
BEGIN
  DELETE
  FROM MOBILE_SCHOOL_NOTIFICATION
  WHERE NOTIFICATION_ID = p_NOTIFICATION_ID;
END;
END SCHOOL_NOTIFICATION_tapi;

/
